@@ -20,6 +20,9 @@ import Foundation
2020#if canImport(AndroidLooper)
2121@_exported import AndroidLooper
2222#endif
23+ #if canImport(AndroidNative)
24+ import AndroidNative
25+ #endif
2326fileprivate let logger : Logger = Logger ( subsystem: " skip.android.bridge " , category: " AndroidBridge " )
2427#endif
2528
@@ -84,8 +87,8 @@ public class AndroidBridgeBootstrap {
8487 try AssetURLProtocol . register ( )
8588 logger. debug ( " initAndroidBridge: bootstrapTimezone " )
8689 try bootstrapTimezone ( )
87- logger. debug ( " initAndroidBridge: bootstrapSSLCertificates " )
88- try bootstrapSSLCertificates ( )
90+ logger. debug ( " initAndroidBridge: setupCACerts " )
91+ try AndroidBootstrap . setupCACerts ( )
8992 logger. debug ( " initAndroidBridge: AndroidLooper.setupMainLooper " )
9093 let _ = AndroidLooper . setupMainLooper ( )
9194 logger. debug ( " initAndroidBridge: done " )
@@ -123,71 +126,6 @@ private func bootstrapFileManagerProperties(filesDir: String, cacheDir: String)
123126 logger. debug ( " bootstrapFileManagerProperties: applicationSupportDirectory= \( applicationSupportDirectory. path) " )
124127}
125128
126- /// Collects all the certificate files from the Android certificate store and writes them to a single `cacerts.pem` file that can be used by libcurl,
127- /// which is communicated through the `URLSessionCertificateAuthorityInfoFile` environment property
128- ///
129- /// See https://android.googlesource.com/platform/frameworks/base/+/8b192b19f264a8829eac2cfaf0b73f6fc188d933%5E%21/#F0
130- /// See https://github.com/apple/swift-nio-ssl/blob/d1088ebe0789d9eea231b40741831f37ab654b61/Sources/NIOSSL/AndroidCABundle.swift#L30
131- private func bootstrapSSLCertificates( fromCertficateFolders certsFolders: [ String ] = [ " /system/etc/security/cacerts " , " /apex/com.android.conscrypt/cacerts " ] ) throws {
132- //let cacheFolder = try FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) // file:////.cache/ (unwritable)
133- let cacheFolder = URL . cachesDirectory
134- logger. debug ( " bootstrapSSLCertificates: \( cacheFolder) " )
135- let generatedCacertsURL = cacheFolder. appendingPathComponent ( " cacerts-aggregate.pem " )
136- logger. debug ( " bootstrapSSLCertificates: generatedCacertsURL= \( generatedCacertsURL) " )
137-
138- let contents = try FileManager . default. contentsOfDirectory ( at: cacheFolder, includingPropertiesForKeys: nil )
139- logger. debug ( " bootstrapSSLCertificates: cacheFolder= \( cacheFolder) contents= \( contents) " )
140-
141- // clear any previous generated certificates file that may have been created by this app
142- if FileManager . default. fileExists ( atPath: generatedCacertsURL. path) {
143- try FileManager . default. removeItem ( atPath: generatedCacertsURL. path)
144- }
145-
146- let created = FileManager . default. createFile ( atPath: generatedCacertsURL. path, contents: nil )
147- logger. debug ( " bootstrapSSLCertificates: created file: \( created) : \( generatedCacertsURL. path) " )
148-
149- let fs = try FileHandle ( forWritingTo: generatedCacertsURL)
150- defer { try ? fs. close ( ) }
151-
152- // write a header
153- fs. write ( """
154- ## Bundle of CA Root Certificates
155- ## Auto-generated on \( Date ( ) )
156- ## by aggregating certificates from: \( certsFolders)
157-
158- """ . data ( using: . utf8) !)
159-
160- // Go through each folder and load each certificate file (ending with ".0"),
161- // and smash them together into a single aggreagate file tha curl can load.
162- // The .0 files will contain some extra metadata, but libcurl only cares about the
163- // -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- sections,
164- // so we can naïvely concatenate them all and libcurl will understand the bundle.
165- for certsFolder in certsFolders {
166- let certsFolderURL = URL ( fileURLWithPath: certsFolder)
167- if ( try ? certsFolderURL. resourceValues ( forKeys: [ . isDirectoryKey] ) . isDirectory) != true { continue }
168- let certURLs = try FileManager . default. contentsOfDirectory ( at: certsFolderURL, includingPropertiesForKeys: [ . isRegularFileKey, . isReadableKey] )
169- for certURL in certURLs {
170- //logger.debug("bootstrapSSLCertificates: certURL=\(certURL)")
171- // certificate files have names like "53a1b57a.0"
172- if certURL. pathExtension != " 0 " { continue }
173- do {
174- if try certURL. resourceValues ( forKeys: [ . isRegularFileKey] ) . isRegularFile == false { continue }
175- if try certURL. resourceValues ( forKeys: [ . isReadableKey] ) . isReadable == false { continue }
176- try fs. write ( contentsOf: try Data ( contentsOf: certURL) )
177- } catch {
178- logger. warning ( " bootstrapSSLCertificates: error reading certificate file \( certURL. path) : \( error) " )
179- continue
180- }
181- }
182- }
183-
184-
185- //setenv("URLSessionCertificateAuthorityInfoFile", "INSECURE_SSL_NO_VERIFY", 1) // disables all certificate verification
186- //setenv("URLSessionCertificateAuthorityInfoFile", "/system/etc/security/cacerts/", 1) // doesn't work for directories
187- setenv ( " URLSessionCertificateAuthorityInfoFile " , generatedCacertsURL. path, 1 )
188- logger. debug ( " bootstrapSSLCertificates: set URLSessionCertificateAuthorityInfoFile= \( generatedCacertsURL. path) " )
189- }
190-
191129// URL.applicationSupportDirectory exists in Darwin's Foundation but not in Android's Foundation
192130#if os(Android)
193131// SKIP @nobridge
0 commit comments