title: Extract Certificate - Unknown password
body: <p>When starting an <code>Activity</code> in  <code>KeyManager</code> I am getting a <code>java.lang.NullPointException</code></p>
  
  <pre><code>public class KeyManager extends Activity implements OnClickListener{
  public KeyManager() {
      super();
  }
  
  public KeyPair createKeyPair(Context c)
  {
      KeyPairGenerator kpg;
      KeyPair kp=null;
      try 
      {
          kpg = KeyPairGenerator.getInstance("RSA");
          kpg.initialize(1024);//1024 bits
          kp = kpg.genKeyPair();
  
          this.savePrivateKeyInKeyChain(kp, c);
          this.savePublicKeyInSharedPreferences(kp, c);
  
      } catch (NoSuchAlgorithmException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (CertificateException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      return kp;
  }
  
  ///////////////////////////////////////
  //////////// KEY CHAIN ////////////////
  ///////////////////////////////////////
  
  public void savePublicKeyInSharedPreferences(KeyPair kp, Context c)
  {
      SharedPreferences sharedPreferences = c.getSharedPreferences("Keys", Context.MODE_PRIVATE);
      SharedPreferences.Editor editor = sharedPreferences.edit();
  
      PublicKey pk=kp.getPublic();
      byte [] pkEncoded=pk.getEncoded();
      Log.i("Public Key", "original encoded:"+pkEncoded);
  
      String publicKeyString=Base64.encodeToString(pkEncoded,false);
      Log.i("Public Key", "encodeToString:"+publicKeyString);
  
      editor.putString("public", publicKeyString);
  
      editor.commit();
  }
  
  public static void savePrivateKeyInKeyChain (KeyPair kp, Context c) throws CertificateException
  {
      Intent intent = KeyChain.createInstallIntent(); 
      byte [] cert=this.getCertificateForPrivateKey(kp);
      Log.i("CERT",""+cert);
      intent.putExtra(KeyChain.EXTRA_CERTIFICATE, cert);
      intent.putExtra(KeyChain.EXTRA_PKCS12, kp.getPrivate().getEncoded());
      c.startActivity(intent);
  }
  
  public static byte [] getCertificateForPrivateKey(KeyPair kp) throws CertificateException
  {
      X500Name name=new X500Name("CN=" + "setichat" + ", OU=None, O=None L=None, C=None");
      BigInteger num=new BigInteger("1");
      Date now=new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30);
      Date after=new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365*10));
      PublicKey pubk=kp.getPublic();
      PrivateKey prik = kp.getPrivate();
  
      X509v3CertificateBuilder builder= new X509v3CertificateBuilder(name, num, now, after, name, SubjectPublicKeyInfo.getInstance(pubk.getEncoded()));
      byte[] certBytes=null;
  
      try 
      {
          certBytes = builder.build(new JCESigner(prik,"SHA256withRSA")).getEncoded();
  
      } catch (IOException e) 
      {
          e.printStackTrace();
      }
  
      CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
      X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(certBytes));
  
      return certificate.getEncoded();
  }
  
  public void saveAliasInSharedPreferences(String alias)
  {
      SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("Alias", Context.MODE_PRIVATE);
      SharedPreferences.Editor editor = sharedPreferences.edit();
  
      editor.putString("alias", alias);
      Log.i("Alias saved", alias);
      editor.commit();
  }
  
  public String getAliasFromSharedPreferences()
  {
      SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("Alias", Context.MODE_PRIVATE);
  
      String a=sharedPreferences.getString("alias", null);
      Log.i("Alias get", a);
      return a;
  }
  
  public String getPrivateKeyFromAlias()
  {
      String alias=getAliasFromSharedPreferences();
      PrivateKey pk=null;
      String result=null;
  
      try 
      {
          pk = KeyChain.getPrivateKey(getApplicationContext(), alias);
          byte [] pkEncoded=pk.getEncoded();
          result=Base64.encodeToString(pkEncoded,false);
          Log.i("Private Key Alias", "encodeToString:"+result);
  
      } catch (KeyChainException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      return result;
  }
  
     public boolean hasKeys(Context c)
  {
      boolean result=false;
      SharedPreferences sharedPreferences = c.getSharedPreferences("Alias", Context.MODE_PRIVATE);
      String p=sharedPreferences.getString("alias", null);
      if(p!=null)
          result=true;
  
      return result;
  }
  
  
  @Override
  public void onClick(DialogInterface arg0, int arg1) {
      // TODO Auto-generated method stub
      KeyChain.choosePrivateKeyAlias(this,
              new KeyChainAliasCallback() {
                  public void alias(String alias) {
                  //Remember the alias selection for future use.
                  if (alias != null) saveAliasInSharedPreferences(alias);
                  }
              },
              null, // List of acceptable key types. null for any
              null, // issuer, null for any
              null, // host name of server requesting the cert, null if unavailable
              -1, // port of server requesting the cert, -1 if unavailable
              null); // alias to preselect, null if unavailable
  }
  
  public X509Certificate[] getCertificateFromAlias(String alias) throws KeyChainException, InterruptedException
  {
      X509Certificate[] chain= KeyChain.getCertificateChain(getApplicationContext(), alias);
      return chain;
  }
   }
  
  class JCESigner implements ContentSigner {
  
  private static final AlgorithmIdentifier PKCS1_SHA256_WITH_RSA_OID = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.1.1.11"));
  
  private Signature signature;
  private ByteArrayOutputStream outputStream;
  
  public JCESigner(PrivateKey privateKey, String signatureAlgorithm) {
      if (!"SHA256withRSA".equals(signatureAlgorithm)) {
          throw new IllegalArgumentException("Signature algorithm \"" + signatureAlgorithm + "\" not yet supported");
      }
      try {
          this.outputStream = new ByteArrayOutputStream();
          this.signature = Signature.getInstance(signatureAlgorithm);
          this.signature.initSign(privateKey);
      } catch (GeneralSecurityException gse) {
          throw new IllegalArgumentException(gse.getMessage());
      }
  }
  
  @Override
  public AlgorithmIdentifier getAlgorithmIdentifier() {
      if (signature.getAlgorithm().equals("SHA256withRSA")) {
          return PKCS1_SHA256_WITH_RSA_OID;
      } else {
          return null;
      }
  }
  
  @Override
  public OutputStream getOutputStream() {
      return outputStream;
  }
  
  @Override
  public byte[] getSignature() {
      try {
          signature.update(outputStream.toByteArray());
          return signature.sign();
      } catch (GeneralSecurityException gse) {
          gse.printStackTrace();
          return null;
      }
  }
  </code></pre>
  
  <p>The value that <code>KeyChain.createInstallIntent()</code> returns is:</p>
  
  <pre><code>04-21 18:31:41.054: I/Intent(1645): Intent { act=android.credentials.INSTALL cmp=com.android.certinstaller/.CertInstallerMain }
  </code></pre>
  
  <p>The code in SettingsFragment.onListItemClick is:</p>
  
  <pre><code>@Override
  public void onListItemClick(ListView l, View v, int position, long id) {
  
      CheckedTextView textview = (CheckedTextView)v;
      textview.setChecked(!textview.isChecked());
  
      if(position==0)
      {
          if(textview.isChecked())
          {
              encrypted=true;
              System.out.println("Encrypted true");
          }
          else
          {   
              encrypted=false;
              System.out.println("Encrypted false");
          }
      }
      else if(position==1)
      {
  
          if(textview.isChecked())
          {
              signed=true;
              System.out.println("Signed True");
  
              if(!KeyManager.hasKeys(l.getContext())){
                  KeyManager.createKeyPair(l.getContext());
                  SeTIKeyUpload upload = new SeTIKeyUpload();
                  String setiUpload = upload.keyUploadString(l.getContext());
                  SeTIChatService mService = SeTIChatServiceBinder.getService();
                  mService.sendMessage(setiUpload);
              }
          }
          else
          {
              signed=false;
              System.out.println("Signed False");
          }   
      }
      System.out.println(position+"position"+", encrypted: "+encrypted+", signed: "+signed);
      SharedPreferences sharedPreferences = v.getContext().getSharedPreferences("Settings", MODE_PRIVATE);
      SharedPreferences.Editor editor = sharedPreferences.edit();
      editor.putBoolean("encrypted", encrypted);
      editor.putBoolean("signed", signed);
      editor.commit();
  }
  </code></pre>
  
  <p>I have checked that the Certificate and PKCS12 are not empty, so the Intent is not empty.</p>
  
  <p>Error console: </p>
  
  <pre><code>04-21 17:17:31.524: E/AndroidRuntime(927): FATAL EXCEPTION: main
  04-21 17:17:31.524: E/AndroidRuntime(927): java.lang.NullPointerException
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.app.Activity.startActivityForResult(Activity.java:3370)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.app.Activity.startActivityForResult(Activity.java:3331)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.app.Activity.startActivity(Activity.java:3566)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.app.Activity.startActivity(Activity.java:3534)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at es.uc3m.setichat.utils.KeyManager.savePrivateKeyInKeyChain(KeyManager.java:288)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at es.uc3m.setichat.utils.KeyManager.createKeyPair(KeyManager.java:188)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at es.uc3m.setichat.activity.SettingsFragment.onListItemClick(SettingsFragment.java:102)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.app.ListFragment$2.onItemClick(ListFragment.java:160)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.widget.AdapterView.performItemClick(AdapterView.java:298)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.widget.AbsListView$PerformClick.run(AbsListView.java:2749)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.widget.AbsListView$1.run(AbsListView.java:3423)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.os.Handler.handleCallback(Handler.java:725)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.os.Handler.dispatchMessage(Handler.java:92)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.os.Looper.loop(Looper.java:137)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at android.app.ActivityThread.main(ActivityThread.java:5039)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at java.lang.reflect.Method.invokeNative(Native Method)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at java.lang.reflect.Method.invoke(Method.java:511)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
  04-21 17:17:31.524: E/AndroidRuntime(927):  at dalvik.system.NativeStart.main(Native Method)
  </code></pre>
  
  <p>And I have defined the class in my AndroidManifest as follows:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="es.uc3m.setichat"
      android:versionCode="1"
      android:versionName="1.0" &gt;
  
      &lt;uses-sdk
          android:minSdkVersion="15"
          android:targetSdkVersion="17" /&gt;
  
      &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
      &lt;uses-permission android:name="android.permission.READ_CONTACTS"/&gt;
  
      &lt;application
          android:allowBackup="true"
          android:icon="@drawable/setichat_icon"
          android:label="@string/app_name"
          android:theme="@style/AppTheme" &gt;
         .
         .
         .
          &lt;activity android:name=".utils.KeyManager"&gt;&lt;/activity&gt;
      &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>
  
  <p><strong>EDIT</strong>:</p>
  
  <p>Now I am able to launch the Intent but the application asks for the password in the "Extract Certificate" window, and I haven't set any password when creating the certificate. Any hints on that?</p>
  
  <p>I have tried to store it with KeyStore, but it makes no difference when typing the password:</p>
  
  <pre><code>KeyStore ks = KeyStore.getInstance("BKS");
  char [] password={'P', 'A', 'S', 'S'};
  ks.load(new ByteArrayInputStream(certBytes), password);
  ks.setKeyEntry("hostname", kp.getPrivate(), password, new java.security.cert.Certificate[] { certificate });
  File keystore = new File("keystore");
  FileOutputStream fos = new FileOutputStream(keystore);
  ks.store(fos, password);
  fos.close();
  </code></pre>