diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 457860a..e636b05 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -82,9 +82,8 @@ jobs: fi if [[ "${{ steps.changes.outputs.swift }}" == "true" ]]; then - # Turning off CodeQL for a while, since it's doesn't work with Swift 6.2.0 - # matrix_include="$(echo "$matrix_include" | jq -c '. += [{"language": "swift", "build-mode": "manual"}]')" - printf '' + matrix_include="$(echo "$matrix_include" | jq -c '. += [{"language": "swift", "build-mode": "manual"}]')" + # printf '' fi echo "matrix={\"include\":$matrix_include}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/templates/prepare-swift/action.yaml b/.github/workflows/templates/prepare-swift/action.yaml index 654f4e9..6647445 100644 --- a/.github/workflows/templates/prepare-swift/action.yaml +++ b/.github/workflows/templates/prepare-swift/action.yaml @@ -42,7 +42,24 @@ runs: apt-get install -y zip fi + - name: Empty mise.toml for Linux + shell: bash + if: ${{ runner.os == 'Linux' }} + run: | + rm -rf mise.toml + touch mise.toml + + - name: Install mise tools + if: ${{ runner.os == 'Linux' }} + uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 + with: + mise_toml: | + [tools] + shfmt = "latest" + shellcheck = "latest" + - name: Install mise tools + if: ${{ runner.os != 'Linux' }} uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 - name: Select Swift Version diff --git a/.version b/.version index 8acdd82..4e379d2 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.0.1 +0.0.2 diff --git a/Package.resolved b/Package.resolved index ca9069c..4130744 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "d8e3b0f50c97b6c2104c325bcb939630ed15a30b91c2ac0e911d6b572996faf0", + "originHash" : "fe48726b149c14339bca212e55d1519f34983eab60f171a81ede97a308510418", "pins" : [ { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-argument-parser.git", "state" : { - "revision" : "309a47b2b1d9b5e991f36961c983ecec72275be3", - "version" : "1.6.1" + "revision" : "626b5b7b2f45e1b0b1c6f4a309296d1d21d7311b", + "version" : "1.7.1" } }, { @@ -24,8 +24,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/swiftlang/swift-cmark.git", "state" : { - "revision" : "b97d09472e847a416629f026eceae0e2afcfad65", - "version" : "0.7.0" + "revision" : "5d9bdaa4228b381639fff09403e39a04926e2dbe", + "version" : "0.7.1" } }, { @@ -34,7 +34,7 @@ "location" : "https://github.com/nekrich/swift-confidential.git", "state" : { "branch" : "master", - "revision" : "c5933c29eefc0850c5957d9dbd5920eda6047480" + "revision" : "51d421bbde6bc27bead4d07148a63ba27ac92d94" } }, { @@ -51,8 +51,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-log.git", "state" : { - "revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2", - "version" : "1.6.4" + "revision" : "bbd81b6725ae874c69e9b8c8804d462356b55523", + "version" : "1.10.1" } }, { @@ -60,8 +60,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-markdown.git", "state" : { - "revision" : "6151fbf2be23b24318cf88617dad5f633820d387", - "version" : "0.7.2" + "revision" : "7d9a5ce307528578dfa777d505496bd5f544ad94", + "version" : "0.7.3" } }, { @@ -87,17 +87,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", "state" : { - "revision" : "4c27acf5394b645b70d8ba19dc249c0472d5f618", - "version" : "1.7.0" + "revision" : "dfd70507def84cb5fb821278448a262c6ff2bbad", + "version" : "1.9.0" } }, { "identity" : "yams", "kind" : "remoteSourceControl", - "location" : "https://github.com/nekrich/Yams.git", + "location" : "https://github.com/jpsim/Yams.git", "state" : { - "branch" : "main", - "revision" : "34a620adced0c58dbbec8b2c4b9eda3d3d06c8a2" + "revision" : "deaf82e867fa2cbd3cd865978b079bfcf384ac28", + "version" : "6.2.1" } } ], diff --git a/Package.swift b/Package.swift index 11089f9..dee8d8a 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ enum SwiftConfidentialSource { var packageDependency: PackageDescription.Package.Dependency { switch self { - case .upstream: .package(url: "https://github.com/securevale/swift-confidential.git", from: "0.4.1") + case .upstream: .package(url: "https://github.com/securevale/swift-confidential.git", from: "0.5.1") case .fork: .package(url: "https://github.com/nekrich/swift-confidential.git", branch: "master") } } @@ -51,14 +51,14 @@ enum YamsSource { var packageDependency: PackageDescription.Package.Dependency { switch self { - case .upstream: .package(url: "https://github.com/jpsim/Yams.git", from: "6.1.0") + case .upstream: .package(url: "https://github.com/jpsim/Yams.git", from: "6.2.1") case .fork: .package(url: "https://github.com/nekrich/Yams.git", branch: "main") } } } let swiftConfidentialSource: SwiftConfidentialSource = .fork -let yamsSource: YamsSource = .fork +let yamsSource: YamsSource = .upstream enum Targets { static func targetBundle( @@ -134,10 +134,7 @@ enum Targets { commandBundle( name: "ObfuscateSecrets", dependencies: [.target(name: "EnvSubst"), .target(name: "Shell"), swiftConfidentialSource.targetDependency], - testsDependencies: [ - .product(name: "ConfidentialKit", package: "swift-confidential", condition: .when(platforms: [.macOS])), - swiftConfidentialSource.targetDependency, - ], + testsDependencies: [swiftConfidentialSource.targetDependency], commandDependencies: [.target(name: "EnvSubstCommand"), .target(name: "ExportSecretsCommand")] ) } @@ -201,7 +198,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMajor(from: "1.6.1")), .package(url: "https://github.com/swiftlang/swift-format.git", .upToNextMajor(from: "602.0.0")), - .package(url: "https://github.com/swiftlang/swift-syntax.git", "602.0.0"..<"603.0.0"), + .package(url: "https://github.com/swiftlang/swift-syntax.git", .upToNextMajor(from: "602.0.0")), .package(url: "https://github.com/apple/swift-log.git", .upToNextMajor(from: "1.6.4")), swiftConfidentialSource.packageDependency, yamsSource.packageDependency, ], diff --git a/Tests/ObfuscateSecretsTests/ConfidentialWrapperTests.swift b/Tests/ObfuscateSecretsTests/ConfidentialWrapperTests.swift index b350e84..0ddb33f 100644 --- a/Tests/ObfuscateSecretsTests/ConfidentialWrapperTests.swift +++ b/Tests/ObfuscateSecretsTests/ConfidentialWrapperTests.swift @@ -1,5 +1,4 @@ -#if canImport(ConfidentialKit) - import ConfidentialKit +#if !os(Linux) import Foundation import Shell import Testing @@ -48,95 +47,23 @@ value: $ENV_VARIABLE_NAME2 """ - /// The resolved values of the obfuscated secret variables. - static let obfuscatedSecretValues: [String: String] = ["variable_name1": "bar", "variable_name2": "baz"] - /// Expected output w/o data and nonce. static let expectedString: String = """ import ConfidentialKit - import Foundation - - extension ConfidentialKit.Obfuscation.Secret { - @ConfidentialKit.Obfuscated(deobfuscateData) - public static var variable_name1: ConfidentialKit.Obfuscation.Secret = .init(data: [], nonce: 0) + extension ConfidentialCore.Obfuscation.Secret { - @ConfidentialKit.Obfuscated(deobfuscateData) - public static var variable_name2: ConfidentialKit.Obfuscation.Secret = .init(data: [], nonce: 0) - - @inline(__always) - private static func deobfuscateData(_ data: Foundation.Data, nonce: Swift.UInt64) throws -> Foundation.Data { - try ConfidentialKit.Obfuscation.Encryption.DataCrypter(algorithm: .aes128GCM) - .deobfuscate(data, nonce: nonce) + public static #Obfuscate(algorithm: .custom([.encrypt(algorithm: .aes128GCM)])) { + let variable_name1 = "bar" + let variable_name2 = "baz" } } """ - // MARK: Regexes - - /// Bytes regex. - /// - /// Matches `0xFF`. First group is the string byte representation: `FF`. - let byteRegex: Regex = /0x([0-9a-fA-F]{1,2}),?\s?+/ - /// Data init regex. - /// - /// Matches `(data: [0xFF, 0xFF...], nonce: 000)`. - let dataReplacementRegex: Regex = #/\(data:\s?+\[((0x([0-9a-fA-F]{1,2}),?\s?+)+)\],\s?+nonce:\s?+(\d+)\)/# - /// Secret variable regex. - /// - /// Matches: `var variableName: Type = .init(data: [0xFF, 0xFF...], nonce: 000)`. - /// First group is the variable name (`variableName`). - /// Third group is the bytes list (`0xFF, 0xFF...`). We match it with the `byteRegex` to get the byte string. - /// Sixth group is the nonce value (`value`). - let secretVariableRegex: Regex = - #/var\s+(.*)\s?+:\s?+.*=\s+.*(\(data:\s?+\[((0x([0-9a-fA-F]{1,2}),?\s?+)+)\],\s?+nonce:\s?+(\d+)\))/# - - // MARK: Validators - - private func validateContentsWithoutDataAndNonce( - obfuscatedString: String, - _ sourceLocation: SourceLocation = #_sourceLocation, - ) throws { - let obfuscatedString = obfuscatedString.replacing(dataReplacementRegex, with: "(data: [], nonce: 0)") - - #expect(obfuscatedString == Self.expectedString, sourceLocation: sourceLocation) - } - - private func validateSecretValues( - _ secretValues: [String: String], - in obfuscatedString: String, - _ sourceLocation: SourceLocation = #_sourceLocation, - ) throws { - let crypter = Obfuscation.Encryption.DataCrypter(algorithm: .aes128GCM) - - let deobfuscationResult = try obfuscatedString.matches(of: secretVariableRegex) - .reduce(into: [String: String]()) { (accum, globalMatch) in - let variableName = String(globalMatch.output.1) - - let obfuscatedBytes = try globalMatch.output.3 // Get matches for all `0xFF` - .matches(of: byteRegex) // Convert to a byte - .map { byteMatch in try #require(UInt8(byteMatch.output.1, radix: 16), sourceLocation: sourceLocation) } - - let nonceValue: UInt64 = try #require(UInt64(globalMatch.output.6), sourceLocation: sourceLocation) - - let secret = ConfidentialKit.Obfuscation.Secret(data: obfuscatedBytes, nonce: nonceValue) - let obfuscated = ConfidentialKit.Obfuscated(wrappedValue: secret, crypter.deobfuscate) - - accum[variableName] = obfuscated.projectedValue - } - - #expect(deobfuscationResult == secretValues, sourceLocation: sourceLocation) - } - - func validate( - outputFileURL: URL, - secretValues: [String: String], - _ sourceLocation: SourceLocation = #_sourceLocation, - ) throws { + func validate(outputFileURL: URL, _ sourceLocation: SourceLocation = #_sourceLocation, ) throws { let obfuscatedString = try String(contentsOf: outputFileURL, encoding: .utf8) - try validateContentsWithoutDataAndNonce(obfuscatedString: obfuscatedString, sourceLocation) - try validateSecretValues(secretValues, in: obfuscatedString, sourceLocation) + #expect(obfuscatedString == Self.expectedString, sourceLocation: sourceLocation) } } @@ -147,7 +74,7 @@ // When running in Xcode: tests run in a temp dir, and mise fails to recognize tool, because is not currently active. // If swift-confidential is not found by /usr/bin/which - install it with mise. if (try? Shell.which(cliToolName: "swift-confidential")) == nil { - do { try Shell.Mise().use(cliToolName: "ubi:securevale/swift-confidential", version: "0.4.1") } + do { try Shell.Mise().use(cliToolName: "github:securevale/swift-confidential", version: "0.5.1") } catch { #expect(Bool(false), "Unexpected error while installing swift-confidential: \(error)") } } @@ -167,7 +94,7 @@ catch { #expect(Bool(false), "Got error: \(error)") } // THEN - try validate(outputFileURL: self.outputFileURL, secretValues: Self.obfuscatedSecretValues) + try validate(outputFileURL: self.outputFileURL) } } @@ -188,7 +115,7 @@ ) // THEN - try validate(outputFileURL: self.outputFileURL, secretValues: Self.obfuscatedSecretValues) + try validate(outputFileURL: self.outputFileURL) } } #endif diff --git a/mise.lock b/mise.lock index fa01aa3..f280db6 100644 --- a/mise.lock +++ b/mise.lock @@ -1,27 +1,116 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html + [[tools.1password]] -version = "2.32.0" -backend = "aqua:1password/cli" +version = "2.33.1" +backend = "vfox:mise-plugins/vfox-1password" + +[tools.1password."platforms.linux-arm64"] +url = "https://cache.agilebits.com/dist/1P/op2/pkg/v2.33.1/op_linux_arm64_v2.33.1.zip" + +[tools.1password."platforms.linux-arm64-musl"] +url = "https://cache.agilebits.com/dist/1P/op2/pkg/v2.33.1/op_linux_arm64_v2.33.1.zip" + +[tools.1password."platforms.linux-x64"] +url = "https://cache.agilebits.com/dist/1P/op2/pkg/v2.33.1/op_linux_amd64_v2.33.1.zip" + +[tools.1password."platforms.linux-x64-musl"] +url = "https://cache.agilebits.com/dist/1P/op2/pkg/v2.33.1/op_linux_amd64_v2.33.1.zip" + +[tools.1password."platforms.macos-arm64"] +url = "https://cache.agilebits.com/dist/1P/op2/pkg/v2.33.1/op_darwin_arm64_v2.33.1.zip" + +[tools.1password."platforms.macos-x64"] +url = "https://cache.agilebits.com/dist/1P/op2/pkg/v2.33.1/op_darwin_amd64_v2.33.1.zip" + +[tools.1password."platforms.windows-x64"] +url = "https://cache.agilebits.com/dist/1P/op2/pkg/v2.33.1/op_windows_amd64_v2.33.1.zip" [[tools.container]] -version = "0.5.0" +version = "0.10.0" backend = "aqua:apple/container" -[tools.container.platforms.macos-arm64] -checksum = "blake3:6363fe6d4aa8391c4c95b203ae2df87e1a6befe5ee6b82661d346965706c28ad" -size = 53214061 -url = "https://github.com/apple/container/releases/download/0.5.0/container-0.5.0-installer-signed.pkg" +[tools.container."platforms.macos-arm64"] +checksum = "sha256:c481ce355524d036c3cddac7fd281e31794d40690bf9a21f732ef3d76fa9fe08" +url = "https://github.com/apple/container/releases/download/0.10.0/container-0.10.0-installer-signed.pkg" + +[tools.container."platforms.macos-x64"] +checksum = "sha256:c481ce355524d036c3cddac7fd281e31794d40690bf9a21f732ef3d76fa9fe08" +url = "https://github.com/apple/container/releases/download/0.10.0/container-0.10.0-installer-signed.pkg" + +[[tools."github:securevale/swift-confidential"]] +version = "0.5.1" +backend = "github:securevale/swift-confidential" + +[tools."github:securevale/swift-confidential"."platforms.macos-arm64"] +checksum = "sha256:b910e2e07720ad799c3f4c01fbe876b4a215d44935677445302e1c3bace3a2e6" +url = "https://github.com/securevale/swift-confidential/releases/download/0.5.1/SwiftConfidentialBinary-macos.artifactbundle.zip" +url_api = "https://api.github.com/repos/securevale/swift-confidential/releases/assets/343969798" + +[tools."github:securevale/swift-confidential"."platforms.macos-x64"] +checksum = "sha256:b910e2e07720ad799c3f4c01fbe876b4a215d44935677445302e1c3bace3a2e6" +url = "https://github.com/securevale/swift-confidential/releases/download/0.5.1/SwiftConfidentialBinary-macos.artifactbundle.zip" +url_api = "https://api.github.com/repos/securevale/swift-confidential/releases/assets/343969798" [[tools.shellcheck]] version = "0.11.0" -backend = "ubi:koalaman/shellcheck" +backend = "aqua:koalaman/shellcheck" + +[tools.shellcheck."platforms.linux-arm64"] +checksum = "sha256:12b331c1d2db6b9eb13cfca64306b1b157a86eb69db83023e261eaa7e7c14588" +url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.aarch64.tar.xz" + +[tools.shellcheck."platforms.linux-arm64-musl"] +checksum = "sha256:12b331c1d2db6b9eb13cfca64306b1b157a86eb69db83023e261eaa7e7c14588" +url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.aarch64.tar.xz" + +[tools.shellcheck."platforms.linux-x64"] +checksum = "sha256:8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198" +url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.x86_64.tar.xz" + +[tools.shellcheck."platforms.linux-x64-musl"] +checksum = "sha256:8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198" +url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.x86_64.tar.xz" + +[tools.shellcheck."platforms.macos-arm64"] +checksum = "sha256:56affdd8de5527894dca6dc3d7e0a99a873b0f004d7aabc30ae407d3f48b0a79" +url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.darwin.aarch64.tar.xz" + +[tools.shellcheck."platforms.macos-x64"] +checksum = "sha256:3c89db4edcab7cf1c27bff178882e0f6f27f7afdf54e859fa041fca10febe4c6" +url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.darwin.x86_64.tar.xz" + +[tools.shellcheck."platforms.windows-x64"] +checksum = "sha256:8a4e35ab0b331c85d73567b12f2a444df187f483e5079ceffa6bda1faa2e740e" +url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.zip" [[tools.shfmt]] -version = "3.12.0" +version = "3.13.0" backend = "aqua:mvdan/sh" -[[tools."ubi:securevale/swift-confidential"]] -version = "0.4.2" -backend = "ubi:securevale/swift-confidential" +[tools.shfmt."platforms.linux-arm64"] +checksum = "sha256:2091a31afd47742051a77bf7cfd175533ab07e924c20ef3151cd108fa1cab5b0" +url = "https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_linux_arm64" + +[tools.shfmt."platforms.linux-arm64-musl"] +checksum = "sha256:2091a31afd47742051a77bf7cfd175533ab07e924c20ef3151cd108fa1cab5b0" +url = "https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_linux_arm64" + +[tools.shfmt."platforms.linux-x64"] +checksum = "sha256:70aa99784703a8d6569bbf0b1e43e1a91906a4166bf1a79de42050a6d0de7551" +url = "https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_linux_amd64" + +[tools.shfmt."platforms.linux-x64-musl"] +checksum = "sha256:70aa99784703a8d6569bbf0b1e43e1a91906a4166bf1a79de42050a6d0de7551" +url = "https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_linux_amd64" + +[tools.shfmt."platforms.macos-arm64"] +checksum = "sha256:650970603b5946dc6041836ddcfa7a19d99b5da885e4687f64575508e99cf718" +url = "https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_darwin_arm64" + +[tools.shfmt."platforms.macos-x64"] +checksum = "sha256:b6890a0009abf71d36d7c536ad56e3132c547ceb77cd5d5ee62b3469ab4e9417" +url = "https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_darwin_amd64" -[tools."ubi:securevale/swift-confidential".platforms.macos-arm64-swift-confidential] -checksum = "blake3:fba4f4ac242d8c5b991961e45662d71a14ada2e4dca556b71d3d22f58d25cd25" +[tools.shfmt."platforms.windows-x64"] +checksum = "sha256:62241aaf6b0ca236f8625d8892784b73fa67ad40bc677a1ad1a64ae395f6a7d5" +url = "https://github.com/mvdan/sh/releases/download/v3.13.0/shfmt_v3.13.0_windows_amd64.exe" diff --git a/mise.toml b/mise.toml index 947d5a4..0b73a75 100644 --- a/mise.toml +++ b/mise.toml @@ -12,12 +12,12 @@ min_version = "2025.9.6" # https://github.com/apple/container/releases/ # Run Linux containers as lightweight virtual machines. # Used in the mise `test-linux` task to run tests in Linux container while running on macOS. -container = "0.5.0" +container = "0.10.0" # https://github.com/securevale/swift-confidential/releases/ # Obfuscation tool for Swift. # Used in ObfuscateSecrets library. -"ubi:securevale/swift-confidential" = "latest" +"github:securevale/swift-confidential" = "latest" # https://github.com/mvdan/sh/releases/ # Formats shell scripts. diff --git a/scripts/tools/swift/swift.sh b/scripts/tools/swift/swift.sh index d3e0d5c..746339d 100755 --- a/scripts/tools/swift/swift.sh +++ b/scripts/tools/swift/swift.sh @@ -18,6 +18,8 @@ swift_install_sdk() { echo "SWIFT_VERSION_SHORT: ${SWIFT_VERSION_SHORT}" SWIFT_SDK_FOLDER="swift-${SWIFT_VERSION_SHORT}-RELEASE_static-linux-0.0.1" + # For Swift 6.3 linux static SDK version is 0.1.0 + # SWIFT_SDK_FOLDER="swift-${SWIFT_VERSION_SHORT}-RELEASE_static-linux-0.1.0" ARTIFACT_BUNDLE_FILE="${SWIFT_SDK_FOLDER}.artifactbundle" if ! swift sdk list | grep "${SWIFT_SDK_FOLDER}" > /dev/null; then @@ -47,6 +49,7 @@ swift_install_sdk() { rm -rf "/tmp/${ARTIFACT_BUNDLE_FILE}.tar.gz" fi + swift sdk list echo "Swift SDK installed" } @@ -66,6 +69,10 @@ swift_run() { "--static-swift-stdlib" "--swift-sdk" "${SWIFT_SDK:-"x86_64-swift-linux-musl"}" ) + elif [ "${ACTION}" == "test" ]; then + DEFAULT_ARGS+=( + "--enable-swift-testing" + ) fi fi