]> git.saurik.com Git - apple/security.git/blobdiff - keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift
Security-59306.11.20.tar.gz
[apple/security.git] / keychain / TrustedPeersHelper / RecoveryKey / RecoveryKey.swift
diff --git a/keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift b/keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift
new file mode 100644 (file)
index 0000000..35cd9b3
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2019 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+import Foundation
+import SecurityFoundation
+
+class RecoveryKey: NSObject {
+    public var recoveryKeys: RecoveryKeySet
+    public var secret: Data
+
+    public var peerKeys: OctagonSelfPeerKeys
+
+    public init(recoveryKeyString: String, recoverySalt: String) throws {
+        self.secret = Data(bytes: Array(recoveryKeyString.utf8), count: recoveryKeyString.utf8.count)
+        self.recoveryKeys = try RecoveryKeySet(secret: self.secret, recoverySalt: recoverySalt)
+
+        let hash = try RecoveryKeySet.hashRecoveryedSigningPublicKey(keyData: self.recoveryKeys.signingKey.publicKey.keyData)
+        let peerID = "RK-" + hash
+
+        try self.peerKeys = OctagonSelfPeerKeys(peerID: peerID, signingKey: self.recoveryKeys.signingKey, encryptionKey: self.recoveryKeys.encryptionKey)
+    }
+}
+
+extension RecoveryKey {
+    enum Error: Swift.Error {
+        case OTErrorDeserializationFailure
+        case OTErrorDecryptionFailure
+        case OTErrorKeyInstantiation
+        case OTErrorKeyMismatch
+        case OTErrorRecoveryCreation
+        case OTErrorAuthCipherTextCreation
+        case OTErrorPrivateKeyCreation
+        case OTErrorRecoveryKeyCreation
+        case OTErrorEntropyCreation
+        case OTErrorEntropyKeyMismatch
+    }
+}
+
+extension RecoveryKey.Error: LocalizedError {
+    public var errorDescription: String? {
+        switch self {
+        case .OTErrorDeserializationFailure:
+            return "Failed to deserialize Recovery peer"
+        case .OTErrorDecryptionFailure:
+            return "could not decrypt Recovery contents"
+        case .OTErrorKeyInstantiation:
+            return "Failed to instantiate octagon peer keys"
+        case .OTErrorKeyMismatch:
+            return "public and private peer signing keys do not match"
+        case .OTErrorRecoveryCreation:
+            return "failed to create Recovery"
+        case .OTErrorAuthCipherTextCreation:
+            return "failed to create authenticated ciphertext"
+        case .OTErrorPrivateKeyCreation:
+            return "failed to create private key"
+        case .OTErrorRecoveryKeyCreation:
+            return "failed to create recovery keys"
+        case .OTErrorEntropyCreation:
+            return "failed to create entropy"
+        case .OTErrorEntropyKeyMismatch:
+            return "keys generated by the entropy+salt do not match the Recovery contents"
+        }
+    }
+}