Skip to content

Commit 7f60e47

Browse files
authored
Merge pull request #13 from skiptools/update-certs
Move certificate bootstrap into swift-android-native
2 parents c7b453b + 6349f85 commit 7f60e47

File tree

3 files changed

+11
-69
lines changed

3 files changed

+11
-69
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ let package = Package(
1414
.package(url: "https://source.skip.tools/skip-foundation.git", from: "1.3.1"),
1515
.package(url: "https://source.skip.tools/swift-jni.git", "0.0.0"..<"2.0.0"),
1616
.package(url: "https://source.skip.tools/skip-bridge.git", "0.0.0"..<"2.0.0"),
17-
.package(url: "https://source.skip.tools/swift-android-native.git", "0.0.0"..<"2.0.0")
17+
.package(url: "https://source.skip.tools/swift-android-native.git", from: "1.4.1")
1818
],
1919
targets: [
2020
.target(name: "SkipAndroidBridge", dependencies: [

Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift

Lines changed: 5 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -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
2326
fileprivate 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

Sources/SkipAndroidBridge/Observation.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ private final class BridgeObservationSupport: @unchecked Sendable {
152152
// Seem like Swift/lib/Threading/Errors.cpp (https://github.com/swiftlang/swift/blob/3934f78ecdd53031ac40d68499f9ee046a5abe50/lib/Threading/Errors.cpp#L13) is missing
153153
// Should be fixed by: https://github.com/swiftlang/swift/pull/77890
154154
@_cdecl("_ZN5swift9threading5fatalEPKcz")
155-
func swiftThreadingFatal() { }
155+
public func swiftThreadingFatal() {
156+
// we need to do *something* here or the function will get stripped out in release mode
157+
print("swiftThreadingFatal")
158+
}
159+
156160
#endif
157161

158162
#endif

0 commit comments

Comments
 (0)