diff --git a/README.md b/README.md index f61f017..ed79bc3 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ You can download the latest release over on the [Releases Page](https://github.c #### Using Homebrew - brew cask install secretive + brew install secretive ### FAQ diff --git a/SecretAgent/InternetAccessPolicy.plist b/SecretAgent/InternetAccessPolicy.plist new file mode 100644 index 0000000..5ef4c38 --- /dev/null +++ b/SecretAgent/InternetAccessPolicy.plist @@ -0,0 +1,31 @@ + + + + + ApplicationDescription + Secretive is an app for storing and managing SSH keys in the Secure Enclave. SecretAgent is a helper process that runs in the background to sign requests, so that you don't always have to keep the main Secretive app open. + DeveloperName + Max Goedjen + Website + https://github.com/maxgoedjen/secretive + Connections + + + IsIncoming + + Host + api.github.com + NetworkProtocol + TCP + Port + 443 + Purpose + Secretive checks GitHub for new versions and security updates. + DenyConsequences + If you deny these connections, you will not be notified about new versions and critical security updates. + + + Services + + + diff --git a/SecretKit/Common/OpenSSH/OpenSSHKeyWriter.swift b/SecretKit/Common/OpenSSH/OpenSSHKeyWriter.swift index 9889835..a577476 100644 --- a/SecretKit/Common/OpenSSH/OpenSSHKeyWriter.swift +++ b/SecretKit/Common/OpenSSH/OpenSSHKeyWriter.swift @@ -19,7 +19,15 @@ public struct OpenSSHKeyWriter { .joined(separator: " ") } - public func openSSHFingerprint(secret: SecretType) -> String { + public func openSSHSHA256Fingerprint(secret: SecretType) -> String { + // OpenSSL format seems to strip the padding at the end. + let base64 = Data(SHA256.hash(data: data(secret: secret))).base64EncodedString() + let paddingRange = base64.index(base64.endIndex, offsetBy: -2)..(secret: SecretType) -> String { Insecure.MD5.hash(data: data(secret: secret)) .compactMap { ("0" + String($0, radix: 16, uppercase: false)).suffix(2) } .joined(separator: ":") diff --git a/SecretKitTests/OpenSSHWriterTests.swift b/SecretKitTests/OpenSSHWriterTests.swift index d7a17b5..fcb0c96 100644 --- a/SecretKitTests/OpenSSHWriterTests.swift +++ b/SecretKitTests/OpenSSHWriterTests.swift @@ -6,8 +6,12 @@ class OpenSSHWriterTests: XCTestCase { let writer = OpenSSHKeyWriter() - func testECDSA256Fingerprint() { - XCTAssertEqual(writer.openSSHFingerprint(secret: Constants.ecdsa256Secret), "dc:60:4d:ff:c2:d9:18:8b:2f:24:40:b5:7f:43:47:e5") + func testECDSA256MD5Fingerprint() { + XCTAssertEqual(writer.openSSHMD5Fingerprint(secret: Constants.ecdsa256Secret), "dc:60:4d:ff:c2:d9:18:8b:2f:24:40:b5:7f:43:47:e5") + } + + func testECDSA256SHA256Fingerprint() { + XCTAssertEqual(writer.openSSHSHA256Fingerprint(secret: Constants.ecdsa256Secret), "SHA256:/VQFeGyM8qKA8rB6WGMuZZxZLJln2UgXLk3F0uTF650") } func testECDSA256PublicKey() { @@ -19,8 +23,12 @@ class OpenSSHWriterTests: XCTestCase { XCTAssertEqual(writer.data(secret: Constants.ecdsa256Secret), Data(base64Encoded: "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOVEjgAA5PHqRgwykjN5qM21uWCHFSY/Sqo5gkHAkn+e1MMQKHOLga7ucB9b3mif33MBid59GRK9GEPVlMiSQwo=")) } - func testECDSA384Fingerprint() { - XCTAssertEqual(writer.openSSHFingerprint(secret: Constants.ecdsa384Secret), "66:e0:66:d7:41:ed:19:8e:e2:20:df:ce:ac:7e:2b:6e") + func testECDSA384MD5Fingerprint() { + XCTAssertEqual(writer.openSSHMD5Fingerprint(secret: Constants.ecdsa384Secret), "66:e0:66:d7:41:ed:19:8e:e2:20:df:ce:ac:7e:2b:6e") + } + + func testECDSA384SHA256Fingerprint() { + XCTAssertEqual(writer.openSSHSHA256Fingerprint(secret: Constants.ecdsa384Secret), "SHA256:GJUEymQNL9ymaMRRJCMGY4rWIJHu/Lm8Yhao/PAiz1I") } func testECDSA384PublicKey() { diff --git a/Secretive.xcodeproj/project.pbxproj b/Secretive.xcodeproj/project.pbxproj index f64ce05..847f536 100644 --- a/Secretive.xcodeproj/project.pbxproj +++ b/Secretive.xcodeproj/project.pbxproj @@ -61,6 +61,8 @@ 508A58B5241ED48F0069DC07 /* PreviewAgentStatusChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508A58B4241ED48F0069DC07 /* PreviewAgentStatusChecker.swift */; }; 508A5911241EF09C0069DC07 /* SecretAgentKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5099A06C240242BA0062B6F2 /* SecretAgentKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 508A5913241EF0B20069DC07 /* SecretKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 50617DA823FCE4AB0099B055 /* SecretKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 508BF28E25B4F005009EFB7E /* InternetAccessPolicy.plist in Resources */ = {isa = PBXBuildFile; fileRef = 508BF28D25B4F005009EFB7E /* InternetAccessPolicy.plist */; }; + 508BF2AA25B4F1CB009EFB7E /* InternetAccessPolicy.plist in Resources */ = {isa = PBXBuildFile; fileRef = 508BF29425B4F140009EFB7E /* InternetAccessPolicy.plist */; }; 5091D2BC25183B830049FD9B /* ApplicationDirectoryController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5091D2BB25183B830049FD9B /* ApplicationDirectoryController.swift */; }; 5091D3222519D56D0049FD9B /* BriefTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5091D3212519D56D0049FD9B /* BriefTests.swift */; }; 5091D3242519D56D0049FD9B /* Brief.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 506772FB2426F3F400034DED /* Brief.framework */; }; @@ -275,6 +277,8 @@ 508A58B2241ED2180069DC07 /* AgentStatusChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgentStatusChecker.swift; sourceTree = ""; }; 508A58B4241ED48F0069DC07 /* PreviewAgentStatusChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewAgentStatusChecker.swift; sourceTree = ""; }; 508A590F241EEF6D0069DC07 /* Secretive.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Secretive.xctestplan; sourceTree = ""; }; + 508BF28D25B4F005009EFB7E /* InternetAccessPolicy.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = InternetAccessPolicy.plist; sourceTree = ""; }; + 508BF29425B4F140009EFB7E /* InternetAccessPolicy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = InternetAccessPolicy.plist; path = SecretAgent/InternetAccessPolicy.plist; sourceTree = SOURCE_ROOT; }; 5091D2BB25183B830049FD9B /* ApplicationDirectoryController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationDirectoryController.swift; sourceTree = ""; }; 5091D31F2519D56D0049FD9B /* BriefTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BriefTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5091D3212519D56D0049FD9B /* BriefTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BriefTests.swift; sourceTree = ""; }; @@ -432,6 +436,7 @@ 508A58B1241ED1EA0069DC07 /* Controllers */, 50617D8623FCE48E0099B055 /* Assets.xcassets */, 50617D8E23FCE48E0099B055 /* Info.plist */, + 508BF28D25B4F005009EFB7E /* InternetAccessPolicy.plist */, 50617D8F23FCE48E0099B055 /* Secretive.entitlements */, 506772C62424784600034DED /* Credits.rtf */, 50617D8823FCE48E0099B055 /* Preview Content */, @@ -633,6 +638,7 @@ 50A3B79024026B7600D209EA /* Assets.xcassets */, 50A3B79524026B7600D209EA /* Main.storyboard */, 50A3B79824026B7600D209EA /* Info.plist */, + 508BF29425B4F140009EFB7E /* InternetAccessPolicy.plist */, 50A3B79924026B7600D209EA /* SecretAgent.entitlements */, 50A3B79224026B7600D209EA /* Preview Content */, ); @@ -925,6 +931,7 @@ 50617D8A23FCE48E0099B055 /* Preview Assets.xcassets in Resources */, 50617D8723FCE48E0099B055 /* Assets.xcassets in Resources */, 506772C72424784600034DED /* Credits.rtf in Resources */, + 508BF28E25B4F005009EFB7E /* InternetAccessPolicy.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -984,6 +991,7 @@ 50A3B79724026B7600D209EA /* Main.storyboard in Resources */, 50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */, 50A3B79124026B7600D209EA /* Assets.xcassets in Resources */, + 508BF2AA25B4F1CB009EFB7E /* InternetAccessPolicy.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Secretive/InternetAccessPolicy.plist b/Secretive/InternetAccessPolicy.plist new file mode 100644 index 0000000..37307a7 --- /dev/null +++ b/Secretive/InternetAccessPolicy.plist @@ -0,0 +1,31 @@ + + + + + ApplicationDescription + Secretive is an app for storing and managing SSH keys in the Secure Enclave + DeveloperName + Max Goedjen + Website + https://github.com/maxgoedjen/secretive + Connections + + + IsIncoming + + Host + api.github.com + NetworkProtocol + TCP + Port + 443 + Purpose + Secretive checks GitHub for new versions and security updates. + DenyConsequences + If you deny these connections, you will not be notified about new versions and critical security updates. + + + Services + + + diff --git a/Secretive/Views/EmptyStoreView.swift b/Secretive/Views/EmptyStoreView.swift index db85890..689b00b 100644 --- a/Secretive/Views/EmptyStoreView.swift +++ b/Secretive/Views/EmptyStoreView.swift @@ -53,14 +53,14 @@ struct EmptyStoreModifiableView: View { CGPoint(x: g.size.width / 2, y: g.size.height * (1/2)), control2: CGPoint(x: g.size.width * (3/4), y: g.size.height * (1/2))) path.addCurve(to: - CGPoint(x: g.size.width, y: 0), control1: - CGPoint(x: g.size.width, y: g.size.height * (1/2)), control2: - CGPoint(x: g.size.width, y: 0)) + CGPoint(x: g.size.width - 13, y: 0), control1: + CGPoint(x: g.size.width - 13 , y: g.size.height * (1/2)), control2: + CGPoint(x: g.size.width - 13, y: 0)) }.stroke(style: StrokeStyle(lineWidth: 5, lineCap: .round)) Path { path in - path.move(to: CGPoint(x: g.size.width - 10, y: 0)) - path.addLine(to: CGPoint(x: g.size.width, y: -10)) - path.addLine(to: CGPoint(x: g.size.width + 10, y: 0)) + path.move(to: CGPoint(x: g.size.width - 23, y: 0)) + path.addLine(to: CGPoint(x: g.size.width - 13, y: -10)) + path.addLine(to: CGPoint(x: g.size.width - 3, y: 0)) }.fill() }.frame(height: (windowGeometry.size.height/2) - 20).padding() Text("No Secrets").bold() diff --git a/Secretive/Views/SecretDetailView.swift b/Secretive/Views/SecretDetailView.swift index ef23e2c..ef7e006 100644 --- a/Secretive/Views/SecretDetailView.swift +++ b/Secretive/Views/SecretDetailView.swift @@ -12,7 +12,10 @@ struct SecretDetailView: View { var body: some View { Form { Section { - CopyableView(title: "Fingerprint", image: Image(systemName: "touchid"), text: keyWriter.openSSHFingerprint(secret: secret)) + CopyableView(title: "SHA256 Fingerprint", image: Image(systemName: "touchid"), text: keyWriter.openSSHSHA256Fingerprint(secret: secret)) + Spacer() + .frame(height: 20) + CopyableView(title: "MD5 Fingerprint", image: Image(systemName: "touchid"), text: keyWriter.openSSHMD5Fingerprint(secret: secret)) Spacer() .frame(height: 20) CopyableView(title: "Public Key", image: Image(systemName: "key"), text: keyString)