import Foundation import Security import Testing @testable import ClientTLS // C-iOS-1 · PKCS#12 import against a real OpenSSL-generated fixture `.p12`, // including the wrong-passphrase and corrupt-file error mappings. @Test("import with the correct passphrase yields an identity whose leaf CN matches") func importSucceedsAndExposesLeaf() throws { // Arrange let data = ClientTLSFixtures.deviceP12Data // Act let identity = try PKCS12Importer.importIdentity( data: data, passphrase: ClientTLSFixtures.passphrase ) // Assert let summary = try #require(identity.summary()) #expect(summary.subjectCommonName == ClientTLSFixtures.leafCommonName) #expect(summary.issuerCommonName == ClientTLSFixtures.issuerCommonName) // 825-day leaf minted at authoring time → not yet expired. #expect(summary.isExpired() == false) } @Test("import drops the leaf from the issuer chain (credential must not repeat it)") func importIssuerChainExcludesLeaf() throws { // Arrange / Act let identity = try PKCS12Importer.importIdentity( data: ClientTLSFixtures.deviceP12Data, passphrase: ClientTLSFixtures.passphrase ) // Assert — fixture chain is [leaf, CA]; issuerCertificates keeps only the CA. let leaf = try #require(identity.leafCertificate()) let leafData = SecCertificateCopyData(leaf) as Data #expect(identity.issuerCertificates.count == 1) for issuer in identity.issuerCertificates { #expect((SecCertificateCopyData(issuer) as Data) != leafData) } } @Test("wrong passphrase maps errSecAuthFailed → .wrongPassphrase") func importWrongPassphrase() { // Arrange / Act / Assert #expect(throws: PKCS12ImportError.wrongPassphrase) { _ = try PKCS12Importer.importIdentity( data: ClientTLSFixtures.deviceP12Data, passphrase: "not-the-passphrase" ) } } @Test("garbage bytes map errSecDecode → .corruptFile") func importCorruptFile() { // Arrange let garbage = Data([0x00, 0x01, 0x02, 0x03, 0x99, 0xAB, 0xCD, 0xEF]) // Act / Assert #expect(throws: PKCS12ImportError.corruptFile) { _ = try PKCS12Importer.importIdentity(data: garbage, passphrase: "x") } } @Test("empty data is treated as a corrupt file, not a crash") func importEmptyData() { #expect(throws: PKCS12ImportError.corruptFile) { _ = try PKCS12Importer.importIdentity(data: Data(), passphrase: "x") } }