Skip to content

Commit

Permalink
Rework tests to skip on macos when entitlement would otherwise cause …
Browse files Browse the repository at this point in the history
…a failure
  • Loading branch information
kdubb committed Oct 17, 2023
1 parent ef3611c commit 9e5dccf
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 148 deletions.
30 changes: 18 additions & 12 deletions ShieldHost/ShieldHost.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
AA5768EC2975E87C00142200 /* DigestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA21523D2975DF5F0072F6CA /* DigestTests.swift */; };
AA5768ED2975E87C00142200 /* CertificateBuilderECTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA21523A2975DF5F0072F6CA /* CertificateBuilderECTests.swift */; };
AA5768EE2975E87C00142200 /* DistinguishedNameParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2152402975DF5F0072F6CA /* DistinguishedNameParserTests.swift */; };
AAC4C7862ADDFFAD00487E0A /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC4C7852ADDFFAD00487E0A /* Utils.swift */; };
AAC4C7872ADDFFAD00487E0A /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC4C7852ADDFFAD00487E0A /* Utils.swift */; };
AADD77C929A3E278005D0955 /* CertificateDecoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AADD77C629A3E278005D0955 /* CertificateDecoderTests.swift */; };
AADD77CA29A3E278005D0955 /* CertificateDecoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AADD77C629A3E278005D0955 /* CertificateDecoderTests.swift */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -104,6 +106,7 @@
AA5768A52975E7C300142200 /* ShieldHostApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShieldHostApp.swift; sourceTree = "<group>"; };
AA5768B22975E7C400142200 /* ShieldHost Watch AppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ShieldHost Watch AppTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
AAC4C7812ADDCBE600487E0A /* ShieldHost Watch App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "ShieldHost Watch App.entitlements"; sourceTree = "<group>"; };
AAC4C7852ADDFFAD00487E0A /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
AADD77C629A3E278005D0955 /* CertificateDecoderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CertificateDecoderTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -199,6 +202,7 @@
AA21523F2975DF5F0072F6CA /* SecIdentityTests.swift */,
AA2152402975DF5F0072F6CA /* DistinguishedNameParserTests.swift */,
AA2152412975DF5F0072F6CA /* SecKeyPairTests.swift */,
AAC4C7852ADDFFAD00487E0A /* Utils.swift */,
);
name = Tests;
path = ../Tests;
Expand Down Expand Up @@ -423,6 +427,7 @@
AA2152452975DF5F0072F6CA /* OIDTests.swift in Sources */,
AA2152462975DF5F0072F6CA /* DistinguishedNameComposerTests.swift in Sources */,
AA2152492975DF5F0072F6CA /* SecKeyTests.swift in Sources */,
AAC4C7862ADDFFAD00487E0A /* Utils.swift in Sources */,
AA21524D2975DF5F0072F6CA /* SecIdentityTests.swift in Sources */,
AA21524A2975DF5F0072F6CA /* SecCertificateTests.swift in Sources */,
AA21524E2975DF5F0072F6CA /* DistinguishedNameParserTests.swift in Sources */,
Expand Down Expand Up @@ -452,6 +457,7 @@
AA5768EE2975E87C00142200 /* DistinguishedNameParserTests.swift in Sources */,
AA5768E72975E87C00142200 /* SecIdentityTests.swift in Sources */,
AA5768EC2975E87C00142200 /* DigestTests.swift in Sources */,
AAC4C7872ADDFFAD00487E0A /* Utils.swift in Sources */,
AA5768E82975E87C00142200 /* CryptorTests.swift in Sources */,
AA5768E22975E87C00142200 /* DistinguishedNameComposerTests.swift in Sources */,
AA5768ED2975E87C00142200 /* CertificateBuilderECTests.swift in Sources */,
Expand Down Expand Up @@ -607,10 +613,10 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShieldHost/ShieldHost.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
Expand Down Expand Up @@ -644,10 +650,10 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShieldHost/ShieldHost.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
Expand Down Expand Up @@ -685,7 +691,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = io.outfoxx.ShieldHostTests;
Expand All @@ -711,7 +717,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = io.outfoxx.ShieldHostTests;
Expand All @@ -734,7 +740,7 @@
CODE_SIGN_ENTITLEMENTS = "ShieldHost Watch App/ShieldHost Watch App.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = ShieldHost;
Expand All @@ -761,7 +767,7 @@
CODE_SIGN_ENTITLEMENTS = "ShieldHost Watch App/ShieldHost Watch App.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = ShieldHost;
Expand Down Expand Up @@ -789,7 +795,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
INFOPLIST_KEY_CFBundleDisplayName = ShieldHost;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = io.outfoxx.ShieldHost;
Expand All @@ -805,7 +811,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
INFOPLIST_KEY_CFBundleDisplayName = ShieldHost;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = io.outfoxx.ShieldHost;
Expand All @@ -823,7 +829,7 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "io.outfoxx.ShieldHost-Watch-AppTests";
Expand All @@ -843,7 +849,7 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 7J5T2VZQJW;
DEVELOPMENT_TEAM = "";
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "io.outfoxx.ShieldHost-Watch-AppTests";
Expand Down
5 changes: 1 addition & 4 deletions ShieldHost/ShieldHost/ShieldHost.entitlements
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>keychain-access-groups</key>
<array/>
</dict>
<dict/>
</plist>
2 changes: 1 addition & 1 deletion Tests/CertificateBuilderECTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CertificateBuilderECTests: XCTestCase {
var keyPair: SecKeyPair!

override func setUpWithError() throws {
keyPair = try SecKeyPair.Builder(type: .ec, keySize: 256).generate(label: "Test")
keyPair = try generateTestKeyPairChecked(type: .ec, keySize: 256, flags: [])
}

override func tearDownWithError() throws {
Expand Down
2 changes: 1 addition & 1 deletion Tests/CertificateBuilderRSATests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CertificateBuilderRSATests: XCTestCase {
var keyPair: SecKeyPair!

override func setUpWithError() throws {
keyPair = try SecKeyPair.Builder(type: .rsa, keySize: 2048).generate(label: "Test")
keyPair = try generateTestKeyPairChecked(type: .rsa, keySize: 2048, flags: [])
}

override func tearDownWithError() throws {
Expand Down
45 changes: 29 additions & 16 deletions Tests/CertificateDecoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,55 +17,57 @@ import XCTest

class CertificateDecoderTests: XCTestCase {

static let outputEnabled = false

func testDecodingTestCerts() throws {

for (title, pem) in Self.certificates {
print("Checking: \(title)")
output("Checking: \(title)")
guard let testCert = try SecCertificate.load(pem: pem).first else {
XCTFail("Failed to load '\(title)'")
continue
}
do {
let decoded = try ASN1.Decoder.decode(Certificate.self, from: testCert.derEncoded)
let subjectName = try NameStringComposer().append(rdnSequence: decoded.tbsCertificate.subject).string
print("Version: \(decoded.tbsCertificate.version)")
print("Serial Number: \(decoded.tbsCertificate.serialNumber.magnitude.serialize())")
print("Subject: \(subjectName)")
output("Version: \(decoded.tbsCertificate.version)")
output("Serial Number: \(decoded.tbsCertificate.serialNumber.magnitude.serialize())")
output("Subject: \(subjectName)")
let issuerName = try NameStringComposer().append(rdnSequence: decoded.tbsCertificate.issuer).string
print("Issuer: \(issuerName)")
print("Validity:")
print(" Not Before: \(decoded.tbsCertificate.validity.notBefore.zonedDate.iso8601EncodedString())")
print(" Not After: \(decoded.tbsCertificate.validity.notAfter.zonedDate.iso8601EncodedString())")
output("Issuer: \(issuerName)")
output("Validity:")
output(" Not Before: \(decoded.tbsCertificate.validity.notBefore.zonedDate.iso8601EncodedString())")
output(" Not After: \(decoded.tbsCertificate.validity.notAfter.zonedDate.iso8601EncodedString())")

for ext in decoded.tbsCertificate.extensions ?? [] {
print("Extension:")
output("Extension:")
switch ext.extnID {
case iso_itu.ds.certificateExtension.basicConstraints.oid:
let basicContstraints = try ASN1Decoder.decode(BasicConstraints.self, from: ext.extnValue)
print(" \(basicContstraints)")
output(" \(basicContstraints)")

case iso_itu.ds.certificateExtension.extKeyUsage.oid:
let extKeyUsage = try ASN1Decoder.decode(ExtKeyUsage.self, from: ext.extnValue)
print(" \(extKeyUsage)")
output(" \(extKeyUsage)")

case iso_itu.ds.certificateExtension.subjectKeyIdentifier.oid:
let subjKeyId = try ASN1Decoder.decode(SubjectKeyIdentifier.self, from: ext.extnValue)
print(" \(subjKeyId)")
output(" \(subjKeyId)")

case iso_itu.ds.certificateExtension.authorityKeyIdentifier.oid:
let authKeyId = try ASN1Decoder.decode(AuthorityKeyIdentifier.self, from: ext.extnValue)
print(" \(authKeyId)")
output(" \(authKeyId)")

case iso_itu.ds.certificateExtension.subjectAltName.oid:
let subjectAltName = try ASN1Decoder.decode(SubjectAltName.self, from: ext.extnValue)
print(" \(subjectAltName)")
output(" \(subjectAltName)")

case iso_itu.ds.certificateExtension.issuerAltName.oid:
let issuerAltName = try ASN1Decoder.decode(IssuerAltName.self, from: ext.extnValue)
print(" \(issuerAltName)")
output(" \(issuerAltName)")

case let oid:
print(" Unknown: \(oid)")
output(" Unknown: \(oid)")
}
}
}
Expand Down Expand Up @@ -175,4 +177,15 @@ class CertificateDecoderTests: XCTestCase {
""",
]

func output(_ value: String) {
guard Self.outputEnabled else { return }
print(value)
}

func output(_ value: Encodable & SchemaSpecified) {
guard Self.outputEnabled else { return }
guard let data = try? value.encoded().base64EncodedString() else { return }
output(data)
}

}
5 changes: 2 additions & 3 deletions Tests/CertificationRequestBuilderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ class CertificationRequestBuilderTests: XCTestCase {
var keyPair: SecKeyPair!

override func setUpWithError() throws {
// Keys are comparatively slow to generate... so we do it once
keyPair = try SecKeyPair.Builder(type: .rsa, keySize: 2048).generate(label: "Test")
keyPair = try generateTestKeyPairChecked(type: .rsa, keySize: 2048, flags: [])
}

override func tearDownWithError() throws {
try keyPair?.delete()
try? keyPair?.delete()
}

func testBuildParse() throws {
Expand Down
43 changes: 37 additions & 6 deletions Tests/SecCertificateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,37 @@ class SecCertificateTests: XCTestCase {
var keyPair: SecKeyPair!

override func setUpWithError() throws {
keyPair = try SecKeyPair.Builder(type: .rsa, keySize: 2048).generate(label: "Test")
keyPair = try generateTestKeyPairChecked(type: .rsa, keySize: 2048, flags: [])
}

override func tearDownWithError() throws {
try? keyPair?.delete()
}

func testAttributesFailForNonPermanentCerts() throws {

let subjectName = try NameBuilder()
.add("Unit Testing", forTypeName: "CN")
.add("123456", forTypeName: "UID")
.name

let issuerName = try NameBuilder()
.add("Test Issuer", forTypeName: "CN")
.name

let certData =
try Certificate.Builder()
.subject(name: subjectName)
.issuer(name: issuerName)
.publicKey(keyPair: keyPair, usage: [.keyCertSign, .cRLSign])
.valid(for: 86400 * 5)
.build(signingKey: keyPair.privateKey, digestAlgorithm: .sha256)
.encoded()

let cert = try SecCertificate.from(data: certData)
XCTAssertThrowsError(try cert.attributes())
}

func testSaveAcccessibilityUnlockedNotShared() throws {

let subjectName = try NameBuilder()
Expand All @@ -49,7 +73,14 @@ class SecCertificateTests: XCTestCase {
let cert = try SecCertificate.from(data: certData)
defer { try? cert.delete() }

try cert.save(accessibility: .unlocked(afterFirst: true, shared: false))
do {
try cert.save(accessibility: .unlocked(afterFirst: true, shared: false))
}
catch SecCertificateError.saveFailed {
#if os(macOS)
throw XCTSkip("Missing keychain entitlement")
#endif
}

let attrs = try cert.attributes()
XCTAssertEqual(attrs[kSecAttrAccessible as String] as? String, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly as String)
Expand Down Expand Up @@ -186,7 +217,7 @@ class SecCertificateTests: XCTestCase {

let rootCert = try SecCertificate.from(data: rootCertData)

let certKeyPair = try SecKeyPair.Builder(type: .ec, keySize: 256).generate()
let certKeyPair = try generateTestKeyPairChecked(type: .ec, keySize: 256, flags: [])
defer { try? certKeyPair.delete() }

let certName = try NameBuilder().add("Unit Testing", forTypeName: "CN").name
Expand Down Expand Up @@ -252,7 +283,7 @@ class SecCertificateTests: XCTestCase {

let rootCert = try SecCertificate.from(data: rootCertData)

let certKeyPair = try SecKeyPair.Builder(type: .ec, keySize: 256).generate()
let certKeyPair = try generateTestKeyPairChecked(type: .ec, keySize: 256, flags: [])
defer { try? certKeyPair.delete() }

let certName = try NameBuilder().add("Unit Testing", forTypeName: "CN").name
Expand Down Expand Up @@ -296,7 +327,7 @@ class SecCertificateTests: XCTestCase {
.encoded()
)

let certKeyPair = try SecKeyPair.Builder(type: .ec, keySize: 256).generate()
let certKeyPair = try generateTestKeyPairChecked(type: .ec, keySize: 256, flags: [])
defer { try? certKeyPair.delete() }

let certName = try NameBuilder().add("Unit Testing", forTypeName: "CN").name
Expand Down Expand Up @@ -344,7 +375,7 @@ class SecCertificateTests: XCTestCase {
.encoded()
)

let certKeyPair = try SecKeyPair.Builder(type: .ec, keySize: 256).generate()
let certKeyPair = try generateTestKeyPairChecked(type: .ec, keySize: 256, flags: [])
defer { try? certKeyPair.delete() }

let certName = try NameBuilder().add("Unit Testing", forTypeName: "CN").name
Expand Down
Loading

0 comments on commit 9e5dccf

Please sign in to comment.