@@ -20,6 +20,9 @@ import Foundation
20
20
#if canImport(AndroidLooper)
21
21
@_exported import AndroidLooper
22
22
#endif
23
+ #if canImport(AndroidNative)
24
+ import AndroidNative
25
+ #endif
23
26
fileprivate let logger : Logger = Logger ( subsystem: " skip.android.bridge " , category: " AndroidBridge " )
24
27
#endif
25
28
@@ -84,8 +87,8 @@ public class AndroidBridgeBootstrap {
84
87
try AssetURLProtocol . register ( )
85
88
logger. debug ( " initAndroidBridge: bootstrapTimezone " )
86
89
try bootstrapTimezone ( )
87
- logger. debug ( " initAndroidBridge: bootstrapSSLCertificates " )
88
- try bootstrapSSLCertificates ( )
90
+ logger. debug ( " initAndroidBridge: setupCACerts " )
91
+ try AndroidBootstrap . setupCACerts ( )
89
92
logger. debug ( " initAndroidBridge: AndroidLooper.setupMainLooper " )
90
93
let _ = AndroidLooper . setupMainLooper ( )
91
94
logger. debug ( " initAndroidBridge: done " )
@@ -123,71 +126,6 @@ private func bootstrapFileManagerProperties(filesDir: String, cacheDir: String)
123
126
logger. debug ( " bootstrapFileManagerProperties: applicationSupportDirectory= \( applicationSupportDirectory. path) " )
124
127
}
125
128
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
-
191
129
// URL.applicationSupportDirectory exists in Darwin's Foundation but not in Android's Foundation
192
130
#if os(Android)
193
131
// SKIP @nobridge
0 commit comments