|
1 | | -#if canImport(ConfidentialKit) |
2 | | - import ConfidentialKit |
| 1 | +#if !os(Linux) |
3 | 2 | import Foundation |
4 | 3 | import Shell |
5 | 4 | import Testing |
|
48 | 47 | value: $ENV_VARIABLE_NAME2 |
49 | 48 | """ |
50 | 49 |
|
51 | | - /// The resolved values of the obfuscated secret variables. |
52 | | - static let obfuscatedSecretValues: [String: String] = ["variable_name1": "bar", "variable_name2": "baz"] |
53 | | - |
54 | 50 | /// Expected output w/o data and nonce. |
55 | 51 | static let expectedString: String = """ |
56 | 52 | import ConfidentialKit |
57 | | - import Foundation |
58 | | -
|
59 | | - extension ConfidentialKit.Obfuscation.Secret { |
60 | 53 |
|
61 | | - @ConfidentialKit.Obfuscated<Swift.String>(deobfuscateData) |
62 | | - public static var variable_name1: ConfidentialKit.Obfuscation.Secret = .init(data: [], nonce: 0) |
| 54 | + extension ConfidentialCore.Obfuscation.Secret { |
63 | 55 |
|
64 | | - @ConfidentialKit.Obfuscated<Swift.String>(deobfuscateData) |
65 | | - public static var variable_name2: ConfidentialKit.Obfuscation.Secret = .init(data: [], nonce: 0) |
66 | | -
|
67 | | - @inline(__always) |
68 | | - private static func deobfuscateData(_ data: Foundation.Data, nonce: Swift.UInt64) throws -> Foundation.Data { |
69 | | - try ConfidentialKit.Obfuscation.Encryption.DataCrypter(algorithm: .aes128GCM) |
70 | | - .deobfuscate(data, nonce: nonce) |
| 56 | + public static #Obfuscate(algorithm: .custom([.encrypt(algorithm: .aes128GCM)])) { |
| 57 | + let variable_name1 = "bar" |
| 58 | + let variable_name2 = "baz" |
71 | 59 | } |
72 | 60 | } |
73 | 61 | """ |
74 | 62 |
|
75 | | - // MARK: Regexes |
76 | | - |
77 | | - /// Bytes regex. |
78 | | - /// |
79 | | - /// Matches `0xFF`. First group is the string byte representation: `FF`. |
80 | | - let byteRegex: Regex = /0x([0-9a-fA-F]{1,2}),?\s?+/ |
81 | | - /// Data init regex. |
82 | | - /// |
83 | | - /// Matches `(data: [0xFF, 0xFF...], nonce: 000)`. |
84 | | - let dataReplacementRegex: Regex = #/\(data:\s?+\[((0x([0-9a-fA-F]{1,2}),?\s?+)+)\],\s?+nonce:\s?+(\d+)\)/# |
85 | | - /// Secret variable regex. |
86 | | - /// |
87 | | - /// Matches: `var variableName: Type = .init(data: [0xFF, 0xFF...], nonce: 000)`. |
88 | | - /// First group is the variable name (`variableName`). |
89 | | - /// Third group is the bytes list (`0xFF, 0xFF...`). We match it with the `byteRegex` to get the byte string. |
90 | | - /// Sixth group is the nonce value (`value`). |
91 | | - let secretVariableRegex: Regex = |
92 | | - #/var\s+(.*)\s?+:\s?+.*=\s+.*(\(data:\s?+\[((0x([0-9a-fA-F]{1,2}),?\s?+)+)\],\s?+nonce:\s?+(\d+)\))/# |
93 | | - |
94 | | - // MARK: Validators |
95 | | - |
96 | | - private func validateContentsWithoutDataAndNonce( |
97 | | - obfuscatedString: String, |
98 | | - _ sourceLocation: SourceLocation = #_sourceLocation, |
99 | | - ) throws { |
100 | | - let obfuscatedString = obfuscatedString.replacing(dataReplacementRegex, with: "(data: [], nonce: 0)") |
101 | | - |
102 | | - #expect(obfuscatedString == Self.expectedString, sourceLocation: sourceLocation) |
103 | | - } |
104 | | - |
105 | | - private func validateSecretValues( |
106 | | - _ secretValues: [String: String], |
107 | | - in obfuscatedString: String, |
108 | | - _ sourceLocation: SourceLocation = #_sourceLocation, |
109 | | - ) throws { |
110 | | - let crypter = Obfuscation.Encryption.DataCrypter(algorithm: .aes128GCM) |
111 | | - |
112 | | - let deobfuscationResult = try obfuscatedString.matches(of: secretVariableRegex) |
113 | | - .reduce(into: [String: String]()) { (accum, globalMatch) in |
114 | | - let variableName = String(globalMatch.output.1) |
115 | | - |
116 | | - let obfuscatedBytes = try globalMatch.output.3 // Get matches for all `0xFF` |
117 | | - .matches(of: byteRegex) // Convert to a byte |
118 | | - .map { byteMatch in try #require(UInt8(byteMatch.output.1, radix: 16), sourceLocation: sourceLocation) } |
119 | | - |
120 | | - let nonceValue: UInt64 = try #require(UInt64(globalMatch.output.6), sourceLocation: sourceLocation) |
121 | | - |
122 | | - let secret = ConfidentialKit.Obfuscation.Secret(data: obfuscatedBytes, nonce: nonceValue) |
123 | | - let obfuscated = ConfidentialKit.Obfuscated<Swift.String>(wrappedValue: secret, crypter.deobfuscate) |
124 | | - |
125 | | - accum[variableName] = obfuscated.projectedValue |
126 | | - } |
127 | | - |
128 | | - #expect(deobfuscationResult == secretValues, sourceLocation: sourceLocation) |
129 | | - } |
130 | | - |
131 | | - func validate( |
132 | | - outputFileURL: URL, |
133 | | - secretValues: [String: String], |
134 | | - _ sourceLocation: SourceLocation = #_sourceLocation, |
135 | | - ) throws { |
| 63 | + func validate(outputFileURL: URL, _ sourceLocation: SourceLocation = #_sourceLocation, ) throws { |
136 | 64 | let obfuscatedString = try String(contentsOf: outputFileURL, encoding: .utf8) |
137 | 65 |
|
138 | | - try validateContentsWithoutDataAndNonce(obfuscatedString: obfuscatedString, sourceLocation) |
139 | | - try validateSecretValues(secretValues, in: obfuscatedString, sourceLocation) |
| 66 | + #expect(obfuscatedString == Self.expectedString, sourceLocation: sourceLocation) |
140 | 67 | } |
141 | 68 | } |
142 | 69 |
|
|
147 | 74 | // When running in Xcode: tests run in a temp dir, and mise fails to recognize tool, because is not currently active. |
148 | 75 | // If swift-confidential is not found by /usr/bin/which - install it with mise. |
149 | 76 | if (try? Shell.which(cliToolName: "swift-confidential")) == nil { |
150 | | - do { try Shell.Mise().use(cliToolName: "ubi:securevale/swift-confidential", version: "0.4.1") } |
| 77 | + do { try Shell.Mise().use(cliToolName: "github:securevale/swift-confidential", version: "0.5.1") } |
151 | 78 | catch { #expect(Bool(false), "Unexpected error while installing swift-confidential: \(error)") } |
152 | 79 | } |
153 | 80 |
|
|
167 | 94 | catch { #expect(Bool(false), "Got error: \(error)") } |
168 | 95 |
|
169 | 96 | // THEN |
170 | | - try validate(outputFileURL: self.outputFileURL, secretValues: Self.obfuscatedSecretValues) |
| 97 | + try validate(outputFileURL: self.outputFileURL) |
171 | 98 | } |
172 | 99 | } |
173 | 100 |
|
|
188 | 115 | ) |
189 | 116 |
|
190 | 117 | // THEN |
191 | | - try validate(outputFileURL: self.outputFileURL, secretValues: Self.obfuscatedSecretValues) |
| 118 | + try validate(outputFileURL: self.outputFileURL) |
192 | 119 | } |
193 | 120 | } |
194 | 121 | #endif |
|
0 commit comments