LocalRepoKeyStore move all creation logic to the constructor
This just makes the code clearer, and the get() method dead simple.
This commit is contained in:
		
							parent
							
								
									b7aad893a3
								
							
						
					
					
						commit
						d5488fc5f1
					
				| @ -2,6 +2,7 @@ | ||||
| package org.fdroid.fdroid.localrepo; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import org.fdroid.fdroid.FDroidApp; | ||||
| import org.spongycastle.asn1.ASN1Sequence; | ||||
| @ -23,7 +24,6 @@ import java.security.cert.CertificateException; | ||||
| import java.security.cert.X509Certificate; | ||||
| import java.util.Calendar; | ||||
| import java.util.Date; | ||||
| import java.util.Formatter; | ||||
| 
 | ||||
| import javax.net.ssl.KeyManager; | ||||
| import javax.net.ssl.KeyManagerFactory; | ||||
| @ -53,79 +53,84 @@ public class LocalRepoKeyStore { | ||||
|     private static LocalRepoKeyStore localRepoKeyStore; | ||||
|     private KeyStore keyStore; | ||||
|     private KeyManager[] keyManagers; | ||||
|     private File backingFile; | ||||
|     private File keyStoreFile; | ||||
| 
 | ||||
|     public static LocalRepoKeyStore get(Context context) { | ||||
|         if (localRepoKeyStore == null) { | ||||
|             File appKeyStoreDir = context.getDir("keystore", Context.MODE_PRIVATE); | ||||
|             File keyStoreFile = new File(appKeyStoreDir, "kerplapp.bks"); | ||||
|             try { | ||||
|                 localRepoKeyStore = new LocalRepoKeyStore(keyStoreFile); | ||||
|             } catch (UnrecoverableKeyException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } catch (KeyStoreException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } catch (NoSuchAlgorithmException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } catch (CertificateException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } catch (OperatorCreationException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } catch (IOException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         } | ||||
|         if (localRepoKeyStore == null) | ||||
|             localRepoKeyStore = new LocalRepoKeyStore(context); | ||||
|         return localRepoKeyStore; | ||||
|     } | ||||
| 
 | ||||
|     private LocalRepoKeyStore(File backingFile) throws KeyStoreException, NoSuchAlgorithmException, | ||||
|             CertificateException, IOException, OperatorCreationException, UnrecoverableKeyException { | ||||
|         this.backingFile = backingFile; | ||||
|         this.keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); | ||||
|     private LocalRepoKeyStore(Context context) { | ||||
|         try { | ||||
|             Log.d(TAG, "generating LocalRepoKeyStore instance"); | ||||
|             File appKeyStoreDir = context.getDir("keystore", Context.MODE_PRIVATE); | ||||
|             this.keyStoreFile = new File(appKeyStoreDir, "kerplapp.bks"); | ||||
|             this.keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); | ||||
| 
 | ||||
|         // If there isn't a persisted BKS keystore on disk we need to | ||||
|         // create a new empty keystore | ||||
|         if (!backingFile.exists()) { | ||||
|             // Init a new keystore with a blank passphrase | ||||
|             keyStore.load(null, "".toCharArray()); | ||||
|         } else { | ||||
|             keyStore.load(new FileInputStream(backingFile), "".toCharArray()); | ||||
|             // If there isn't a persisted BKS keystore on disk we need to | ||||
|             // create a new empty keystore | ||||
|             if (!keyStoreFile.exists()) { | ||||
|                 // Init a new keystore with a blank passphrase | ||||
|                 keyStore.load(null, "".toCharArray()); | ||||
|             } else { | ||||
|                 keyStore.load(new FileInputStream(keyStoreFile), "".toCharArray()); | ||||
|             } | ||||
| 
 | ||||
|             /* | ||||
|              * If the keystore we loaded doesn't have an INDEX_CERT_ALIAS entry | ||||
|              * we need to generate a new random keypair and a self signed | ||||
|              * certificate for this slot. | ||||
|              */ | ||||
|             if (keyStore.getKey(INDEX_CERT_ALIAS, "".toCharArray()) == null) { | ||||
|                 /* | ||||
|                  * Generate a random key pair to associate with the | ||||
|                  * INDEX_CERT_ALIAS certificate in the keystore. This keypair | ||||
|                  * will be used for the HTTPS cert as well. | ||||
|                  */ | ||||
|                 KeyPair rndKeys = generateRandomKeypair(); | ||||
| 
 | ||||
|                 /* | ||||
|                  * Generate a self signed certificate for signing the index.jar | ||||
|                  * We can't generate the HTTPS certificate until we know what | ||||
|                  * the IP address will be to use for the CN field. | ||||
|                  */ | ||||
|                 X500Name subject = new X500Name(DEFAULT_INDEX_CERT_INFO); | ||||
|                 Certificate indexCert = generateSelfSignedCertChain(rndKeys, subject); | ||||
| 
 | ||||
|                 addToStore(INDEX_CERT_ALIAS, rndKeys, indexCert); | ||||
|             } | ||||
| 
 | ||||
|             /* | ||||
|              * Kerplapp uses its own KeyManager to to ensure the correct | ||||
|              * keystore alias is used for the correct purpose. With the default | ||||
|              * key manager it is not possible to specify that HTTP_CERT_ALIAS | ||||
|              * should be used for TLS and INDEX_CERT_ALIAS for signing the | ||||
|              * index.jar. | ||||
|              */ | ||||
|             KeyManagerFactory keyManagerFactory = KeyManagerFactory | ||||
|                     .getInstance(KeyManagerFactory.getDefaultAlgorithm()); | ||||
| 
 | ||||
|             keyManagerFactory.init(keyStore, "".toCharArray()); | ||||
|             KeyManager defaultKeyManager = keyManagerFactory.getKeyManagers()[0]; | ||||
|             KeyManager wrappedKeyManager = new KerplappKeyManager( | ||||
|                     (X509KeyManager) defaultKeyManager); | ||||
|             keyManagers = new KeyManager[] { | ||||
|                     wrappedKeyManager | ||||
|             }; | ||||
|         } catch (UnrecoverableKeyException e) { | ||||
|             e.printStackTrace(); | ||||
|         } catch (KeyStoreException e) { | ||||
|             e.printStackTrace(); | ||||
|         } catch (NoSuchAlgorithmException e) { | ||||
|             e.printStackTrace(); | ||||
|         } catch (CertificateException e) { | ||||
|             e.printStackTrace(); | ||||
|         } catch (OperatorCreationException e) { | ||||
|             e.printStackTrace(); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
|          * If the keystore we loaded doesn't have an INDEX_CERT_ALIAS entry we | ||||
|          * need to generate a new random keypair and a self signed certificate | ||||
|          * for this slot. | ||||
|          */ | ||||
|         if (keyStore.getKey(INDEX_CERT_ALIAS, "".toCharArray()) == null) { | ||||
|             // Generate a random key pair to associate with the INDEX_CERT_ALIAS | ||||
|             // certificate in the keystore. This keypair will be used for the | ||||
|             // HTTPS cert as well. | ||||
|             KeyPair rndKeys = generateRandomKeypair(); | ||||
| 
 | ||||
|             // Generate a self signed certificate for signing the index.jar | ||||
|             // We can't generate the HTTPS certificate until we know what the IP | ||||
|             // address will be to use for the CN field. | ||||
|             X500Name subject = new X500Name(DEFAULT_INDEX_CERT_INFO); | ||||
|             Certificate indexCert = generateSelfSignedCertChain(rndKeys, subject); | ||||
| 
 | ||||
|             addToStore(INDEX_CERT_ALIAS, rndKeys, indexCert); | ||||
|         } | ||||
| 
 | ||||
|         // Kerplapp uses its own KeyManager to to ensure the correct keystore | ||||
|         // alias is used for the correct purpose. With the default key manager | ||||
|         // it is not possible to specify that HTTP_CERT_ALIAS should be used for | ||||
|         // TLS and INDEX_CERT_ALIAS for signing the index.jar. | ||||
|         KeyManagerFactory keyManagerFactory = KeyManagerFactory | ||||
|                 .getInstance(KeyManagerFactory.getDefaultAlgorithm()); | ||||
| 
 | ||||
|         keyManagerFactory.init(keyStore, "".toCharArray()); | ||||
|         KeyManager defaultKeyManager = keyManagerFactory.getKeyManagers()[0]; | ||||
|         KeyManager wrappedKeyManager = new KerplappKeyManager( | ||||
|                 (X509KeyManager) defaultKeyManager); | ||||
|         keyManagers = new KeyManager[] { | ||||
|                 wrappedKeyManager | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     public void setupHTTPSCertificate() throws CertificateException, | ||||
| @ -149,7 +154,7 @@ public class LocalRepoKeyStore { | ||||
|     } | ||||
| 
 | ||||
|     public File getKeyStoreFile() { | ||||
|         return backingFile; | ||||
|         return keyStoreFile; | ||||
|     } | ||||
| 
 | ||||
|     public KeyStore getKeyStore() { | ||||
| @ -235,7 +240,7 @@ public class LocalRepoKeyStore { | ||||
|         keyStore.setKeyEntry(alias, kp.getPrivate(), | ||||
|                 "".toCharArray(), chain); | ||||
| 
 | ||||
|         keyStore.store(new FileOutputStream(backingFile), "".toCharArray()); | ||||
|         keyStore.store(new FileOutputStream(keyStoreFile), "".toCharArray()); | ||||
| 
 | ||||
|         /* | ||||
|          * After adding an entry to the keystore we need to create a fresh | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Hans-Christoph Steiner
						Hans-Christoph Steiner