Generate SSD pinned TLS factory from typed Jerboa
ober
389657b27b8496b79783e8a50aab012d26d2a686
--- a/templates/ssd-review.ss +++ b/templates/ssd-review.ss @@ -15575,16 +15575,24 @@ (java nio file StandardOpenOption) (java security MessageDigest) (java security PublicKey) + (java security KeyStore) + (java security SecureRandom) (java time Instant) (java time OffsetDateTime) (java time format DateTimeFormatter) (java security cert Certificate) + (java security cert CertificateException) (java util zip ZipEntry) (java util zip ZipInputStream) (java util zip ZipOutputStream) (javax net ssl HttpsURLConnection) + (javax net ssl KeyManager) + (javax net ssl SSLContext) (javax net ssl SSLPeerUnverifiedException) (javax net ssl SSLSocketFactory) + (javax net ssl TrustManager) + (javax net ssl TrustManagerFactory) + (javax net ssl X509TrustManager) (androidx documentfile provider DocumentFile) (org json JSONArray) (org json JSONObject)) @@ -15600,6 +15608,7 @@ truthStoreLoadRemoteConfigLocal truthStoreRemoteUrlLocal truthStoreOpenPinnedConnectionLocal + truthStorePinnedSocketFactoryLocal truthStoreInvalidateTruthIndexLocal truthStoreTruthIndexEntriesLocal truthStoreTruthIndexEntryLocal @@ -15636,6 +15645,7 @@ (type BufferedInputStream) (type BufferedOutputStream) (type Certificate) + (type CertificateException) (type Char) (type ContentResolver) (type Context) @@ -15650,6 +15660,8 @@ (type LinkOption) (type LimitedInputStream) (type HttpsURLConnection) + (type KeyStore) + (type KeyManager) (type MessageDigest) (type Number) (type OffsetDateTime) @@ -15657,18 +15669,23 @@ (type Path) (type PublicKey) (type RemoteConfig) + (type SSLContext) (type SSLPeerUnverifiedException) (type SSLSocketFactory) + (type SecureRandom) (type SsdSession) (type SharedPreferences) (type StorageStats) (type StandardCopyOption) (type StandardOpenOption) + (type TrustManager) + (type TrustManagerFactory) (type TruthIndexEntry) (type TruthStore) (type Uri) (type URL) (type URLConnection) + (type X509TrustManager) (type JSONArray) (type JSONObject) (type ZipEntry) @@ -16150,6 +16167,44 @@ (extern (truthStoreSslPeerUnverifiedException (message : String)) : SSLPeerUnverifiedException (kotlin-call SSLPeerUnverifiedException)) + (extern (truthStoreCertificateException + (message : String)) : CertificateException + (kotlin-call CertificateException)) + (extern (truthStoreTrustManagerFactoryDefaultAlgorithm) : String + (kotlin-call TrustManagerFactory getDefaultAlgorithm)) + (extern (truthStoreTrustManagerFactoryGetInstance + (algorithm : String)) : TrustManagerFactory + (kotlin-call TrustManagerFactory getInstance)) + (extern (truthStoreTrustManagerFactoryInit + (factory : TrustManagerFactory) + (store : (Nullable KeyStore))) : Unit + (kotlin-member-call init)) + (extern (truthStoreNullAsKeyStore + (value : (Nullable Any))) : (Nullable KeyStore) + (kotlin-cast KeyStore)) + (extern (truthStoreTrustManagers + (factory : TrustManagerFactory)) : (Array TrustManager) + (kotlin-member-get trustManagers)) + (extern (truthStoreTrustManagerAsX509 + (manager : TrustManager)) : (Nullable X509TrustManager) + (kotlin-safe-cast X509TrustManager)) + (extern (truthStoreTrustManagerArrayOfPinned + (manager : X509TrustManager)) : (Array TrustManager) + (kotlin-call arrayOf)) + (extern (truthStoreSslContextGetInstance + (protocol : String)) : SSLContext + (kotlin-call SSLContext getInstance)) + (extern (truthStoreSecureRandom) : SecureRandom + (kotlin-call SecureRandom)) + (extern (truthStoreSslContextInit + (context : SSLContext) + (keyManagers : (Nullable (Array KeyManager))) + (trustManagers : (Array TrustManager)) + (random : SecureRandom)) : Unit + (kotlin-member-call init)) + (extern (truthStoreSslContextSocketFactory + (context : SSLContext)) : SSLSocketFactory + (kotlin-member-get socketFactory)) (extern (truthStoreMaxZipEntryBytes) : Int (kotlin-value MAX_ZIP_ENTRY_BYTES)) (extern (truthStoreMaxHttpTextBytes) : Int @@ -16709,6 +16764,74 @@ connection config) connection)))) + (def (truthStorePinnedExpectedPinLocal + (config : RemoteConfig)) : Bytes + (if (remotePinBytesPresent + (RemoteConfig-spkiSha256 config)) + (nullable-get (RemoteConfig-spkiSha256 config)) + (throw + (truthStoreCertificateException + "SPKI pin is required for pinned TLS") + Bytes))) + (def (truthStoreX509TrustManagerSearchStep + (search : (Pair Int32 (Nullable X509TrustManager))) + (candidate : (Nullable X509TrustManager))) : (Pair Int32 (Nullable X509TrustManager)) + (if (nullable-null? candidate) + search + (pair + (+ (pair-first search) (int32 1)) + candidate))) + (def (truthStoreSingleX509TrustManagerLocal + (managers : (Array TrustManager))) : X509TrustManager + (let ((search + (for/fold ((state + (pair + (int32 0) + (nullable-none X509TrustManager)))) + ((i (in-range + (int32 0) + (list-size managers)))) + (truthStoreX509TrustManagerSearchStep + state + (truthStoreTrustManagerAsX509 + (list-ref managers i)))))) + (if (= (pair-first search) (int32 1)) + (nullable-get (pair-second search)) + (throw + (truthStoreCertificateException + "Expected exactly one platform X509 trust manager") + X509TrustManager)))) + (def (truthStoreDefaultTrustManagerFactoryLocal) : TrustManagerFactory + (let ((factory + (truthStoreTrustManagerFactoryGetInstance + (truthStoreTrustManagerFactoryDefaultAlgorithm)))) + (begin + (truthStoreTrustManagerFactoryInit + factory + (truthStoreNullAsKeyStore + (nullable-none Any))) + factory))) + (def (truthStorePinnedSocketFactoryLocal + (config : RemoteConfig)) : SSLSocketFactory + (let ((expectedPin + (truthStorePinnedExpectedPinLocal config))) + (let ((platform + (truthStoreSingleX509TrustManagerLocal + (truthStoreTrustManagers + (truthStoreDefaultTrustManagerFactoryLocal))))) + (let ((pinned + (truthStoreMakePinnedTrustManager + platform + expectedPin))) + (let ((context + (truthStoreSslContextGetInstance "TLS"))) + (begin + (truthStoreSslContextInit + context + (nullable-none (Array KeyManager)) + (truthStoreTrustManagerArrayOfPinned pinned) + (truthStoreSecureRandom)) + (truthStoreSslContextSocketFactory context))))))) (def (truthStoreReadResponseTextLocal (connection : HttpsURLConnection)) : String (begin @@ -18533,17 +18656,8 @@ " ): HttpsURLConnection =" " truthStoreOpenPinnedConnectionLocal(this, relative, method, outputBytes, contentType, acceptGzip)" "" - " internal fun pinnedSocketFactory(config: RemoteConfig): SSLSocketFactory {" - " if (!remotePinBytesPresent(config.spkiSha256)) throw CertificateException(\"SPKI pin is required for pinned TLS\")" - " val expectedPin = checkNotNull(config.spkiSha256)" - " val managerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())" - " managerFactory.init(null as KeyStore?)" - " val platform = managerFactory.trustManagers.filterIsInstance<X509TrustManager>().single()" - " val pinned = truthStoreMakePinnedTrustManager(platform, expectedPin)" - " return SSLContext.getInstance(\"TLS\").apply {" - " init(null, arrayOf<TrustManager>(pinned), SecureRandom())" - " }.socketFactory" - " }" + " internal fun pinnedSocketFactory(config: RemoteConfig): SSLSocketFactory =" + " truthStorePinnedSocketFactoryLocal(config)" "" " fun pullRemoteTruth(session: SsdSession): Int =" " truthStorePullRemoteTruthLocal(this, session)"