Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
linphone-iphone
Commits
443152f8
Commit
443152f8
authored
Apr 06, 2021
by
Christophe Deschamps
Committed by
DanmeiChen
Apr 07, 2021
Browse files
VFS key generation & store/retrieve to/from keystore & pass on to factory if vfs enabled
parent
765f449c
Pipeline
#27490
failed with stage
in 12 seconds
Changes
3
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
192 additions
and
0 deletions
+192
-0
Classes/LinphoneAppDelegate.m
Classes/LinphoneAppDelegate.m
+8
-0
Classes/VFSUtil.swift
Classes/VFSUtil.swift
+180
-0
linphone.xcodeproj/project.pbxproj
linphone.xcodeproj/project.pbxproj
+4
-0
No files found.
Classes/LinphoneAppDelegate.m
View file @
443152f8
...
...
@@ -33,6 +33,8 @@
#import <Intents/Intents.h>
#import <IntentsUI/IntentsUI.h>
#import "linphoneapp-Swift.h"
#ifdef USE_CRASHLYTICS
#include "FIRApp.h"
...
...
@@ -263,6 +265,12 @@
#ifdef USE_CRASHLYTICS
[
FIRApp
configure
];
#endif
if
([[
NSUserDefaults
standardUserDefaults
]
boolForKey
:
@"vfs_enabled"
]
&&
!
VFSUtil
.
activateVFS
)
{
[
VFSUtil
oslogWithLog
:
@"[VFS] Error unable to activate."
level
:
OS_LOG_TYPE_ERROR
];
}
UIApplication
*
app
=
[
UIApplication
sharedApplication
];
UIApplicationState
state
=
app
.
applicationState
;
...
...
Classes/VFSUtil.swift
0 → 100644
View file @
443152f8
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import
UIKit
import
Foundation
import
Security
import
CommonCrypto
import
linphonesw
import
os
@objc
class
VFSUtil
:
NSObject
{
@objc
static
let
keyName
=
Bundle
.
main
.
bundleIdentifier
!+
".vfskey"
@objc
static
let
prefName
=
Bundle
.
main
.
bundleIdentifier
!+
".vfspref"
@objc
static
func
generateKey
(
requiresBiometry
:
Bool
=
false
)
throws
{
let
flags
:
SecAccessControlCreateFlags
if
#available(iOS 11.3, *)
{
flags
=
requiresBiometry
?
[
.
privateKeyUsage
,
.
biometryCurrentSet
]
:
.
privateKeyUsage
}
else
{
flags
=
requiresBiometry
?
[
.
privateKeyUsage
,
.
touchIDCurrentSet
]
:
.
privateKeyUsage
}
let
access
=
SecAccessControlCreateWithFlags
(
kCFAllocatorDefault
,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
,
flags
,
nil
)
!
let
tag
=
keyName
.
data
(
using
:
.
utf8
)
!
let
attributes
:
[
String
:
Any
]
=
[
kSecAttrKeyType
as
String
:
kSecAttrKeyTypeECSECPrimeRandom
,
kSecAttrKeySizeInBits
as
String
:
256
,
kSecAttrTokenID
as
String
:
kSecAttrTokenIDSecureEnclave
,
kSecPrivateKeyAttrs
as
String
:
[
kSecAttrIsPermanent
as
String
:
true
,
kSecAttrApplicationTag
as
String
:
tag
,
kSecAttrAccessControl
as
String
:
access
]
]
var
error
:
Unmanaged
<
CFError
>
?
guard
let
_
=
SecKeyCreateRandomKey
(
attributes
as
CFDictionary
,
&
error
)
else
{
throw
error
!.
takeRetainedValue
()
as
Error
}
}
@objc
static
func
loadKey
(
name
:
String
)
->
SecKey
?
{
let
tag
=
name
.
data
(
using
:
.
utf8
)
!
let
query
:
[
String
:
Any
]
=
[
kSecClass
as
String
:
kSecClassKey
,
kSecAttrApplicationTag
as
String
:
tag
,
kSecAttrKeyType
as
String
:
kSecAttrKeyTypeEC
,
kSecReturnRef
as
String
:
true
]
var
item
:
CFTypeRef
?
let
status
=
SecItemCopyMatching
(
query
as
CFDictionary
,
&
item
)
guard
status
==
errSecSuccess
else
{
return
nil
}
return
(
item
as!
SecKey
)
}
@objc
static
func
encrypt
(
clearText
:
String
)
->
String
?
{
let
algorithm
:
SecKeyAlgorithm
=
.
eciesEncryptionCofactorX963SHA512AESGCM
guard
let
privateKey
=
loadKey
(
name
:
keyName
),
let
publicKey
=
SecKeyCopyPublicKey
(
privateKey
),
SecKeyIsAlgorithmSupported
(
publicKey
,
.
encrypt
,
algorithm
)
else
{
return
nil
}
var
error
:
Unmanaged
<
CFError
>
?
let
clearTextData
=
clearText
.
data
(
using
:
.
utf8
)
!
guard
let
encryptedData
=
SecKeyCreateEncryptedData
(
publicKey
,
algorithm
,
clearTextData
as
CFData
,
&
error
)
as
Data
?
else
{
return
nil
}
return
encryptedData
.
base64EncodedString
()
}
@objc
static
func
decrypt
(
encryptedText
:
String
)
->
String
?
{
let
algorithm
:
SecKeyAlgorithm
=
.
eciesEncryptionCofactorX963SHA512AESGCM
guard
let
key
=
loadKey
(
name
:
keyName
),
SecKeyIsAlgorithmSupported
(
key
,
.
decrypt
,
algorithm
)
else
{
return
nil
}
var
error
:
Unmanaged
<
CFError
>
?
guard
let
clearTextData
=
SecKeyCreateDecryptedData
(
key
,
algorithm
,
Data
(
base64Encoded
:
encryptedText
)
!
as
CFData
,
&
error
)
as
Data
?
else
{
print
(
"[VFS] failed deciphering data
\(
String
(
describing
:
error
)
)
"
)
return
nil
}
return
String
(
decoding
:
clearTextData
,
as
:
UTF8
.
self
)
}
@objc
static
func
addSecuredPreference
(
key
:
String
,
value
:
String
)
->
Bool
{
let
delQuery
:
[
String
:
Any
]
=
[
kSecClass
as
String
:
kSecClassGenericPassword
,
kSecAttrAccount
as
String
:
key
.
data
(
using
:
.
utf8
)
!
]
SecItemDelete
(
delQuery
as
CFDictionary
)
let
insertQUery
:
[
String
:
Any
]
=
[
kSecClass
as
String
:
kSecClassGenericPassword
,
kSecAttrAccount
as
String
:
key
.
data
(
using
:
.
utf8
)
!
,
kSecValueData
as
String
:
value
.
data
(
using
:
.
utf8
)
!
]
let
insertStatus
=
SecItemAdd
(
insertQUery
as
CFDictionary
,
nil
)
return
insertStatus
==
errSecSuccess
}
@objc
static
func
getSecuredPreference
(
key
:
String
)
->
String
?
{
let
query
:
[
String
:
Any
]
=
[
kSecClass
as
String
:
kSecClassGenericPassword
,
kSecAttrAccount
as
String
:
key
.
data
(
using
:
.
utf8
)
!
,
kSecReturnData
as
String
:
kCFBooleanTrue
]
var
result
:
AnyObject
?
let
status
:
OSStatus
=
withUnsafeMutablePointer
(
to
:
&
result
)
{
SecItemCopyMatching
(
query
as
CFDictionary
,
UnsafeMutablePointer
(
$0
))
}
return
status
==
errSecSuccess
?
String
(
decoding
:
result
as!
Data
,
as
:
UTF8
.
self
)
:
nil
}
@objc
static
func
randomSha512
()
->
String
{
let
data
=
UUID
.
init
()
.
uuidString
.
data
(
using
:
.
utf8
)
!
var
digest
=
[
UInt8
](
repeating
:
0
,
count
:
Int
(
CC_SHA512_DIGEST_LENGTH
))
data
.
withUnsafeBytes
({
_
=
CC_SHA512
(
$0
,
CC_LONG
(
data
.
count
),
&
digest
)
})
return
digest
.
map
({
String
(
format
:
"%02hhx"
,
$0
)
})
.
joined
(
separator
:
""
)
}
@objc
static
func
activateVFS
()
->
Bool
{
do
{
if
(
getSecuredPreference
(
key
:
prefName
)
==
nil
)
{
oslog
(
log
:
"[VFS] no secret key set, building one."
,
level
:
.
info
)
try
generateKey
(
requiresBiometry
:
false
)
guard
let
encryptedHash
=
encrypt
(
clearText
:
randomSha512
())
else
{
return
false
}
if
(
!
addSecuredPreference
(
key
:
prefName
,
value
:
encryptedHash
))
{
oslog
(
log
:
"[VFS] Unable to save encrypted key in secured defaults."
,
level
:
.
error
)
}
}
guard
let
encryptedKey
=
getSecuredPreference
(
key
:
prefName
)
else
{
oslog
(
log
:
"[VFS] Unable to retrieve encrypted key."
,
level
:
.
error
)
return
false
}
let
secret
=
decrypt
(
encryptedText
:
encryptedKey
)
Factory
.
Instance
.
setVfsEncryption
(
encryptionModule
:
2
,
secret
:
secret
,
secretSize
:
32
)
oslog
(
log
:
"[VFS] activated"
,
level
:
.
info
)
return
true
}
catch
{
oslog
(
log
:
"[VFS] Error setting up VFS:
\(
error
)
"
,
level
:
.
info
)
return
false
}
}
@objc
static
func
oslog
(
log
:
String
,
level
:
OSLogType
)
{
if
#available(iOS 10.0, *)
{
os_log
(
"%{public}@"
,
type
:
level
,
log
)
}
else
{
NSLog
(
log
)
}
}
}
linphone.xcodeproj/project.pbxproj
View file @
443152f8
...
...
@@ -673,6 +673,7 @@
8CF25D9E1F9F76BD00BEA0C1 /* chat_group_informations@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8CF25D9C1F9F76BD00BEA0C1 /* chat_group_informations@2x.png */; };
93566413F75DA69D2811A716 /* Pods_msgNotificationService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F30EA7BEA39DA427CE0754E /* Pods_msgNotificationService.framework */; };
A634ABAFCB39B6AAE4CA991D /* Pods_linphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65CEDD144CABFAA70A29AF27 /* Pods_linphone.framework */; };
C6DA657C261C950C0020CB43 /* VFSUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6DA657B261C950C0020CB43 /* VFSUtil.swift */; };
C90FAA7915AF54E6002091CB /* HistoryDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */; };
CF15F21E20E4F9A3008B1DE6 /* UIImageViewDeletable.m in Sources */ = {isa = PBXBuildFile; fileRef = CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */; };
CF15F21F20E4F9A3008B1DE6 /* UIImageViewDeletable.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */; };
...
...
@@ -1705,6 +1706,7 @@
ADCA571A7CF61077747BFE53 /* Pods-msgNotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-msgNotificationService.debug.xcconfig"; path = "Pods/Target Support Files/Pods-msgNotificationService/Pods-msgNotificationService.debug.xcconfig"; sourceTree = "<group>"; };
BAD0A9494E833034EB559687 /* Pods-msgNotificationContent.distributionadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-msgNotificationContent.distributionadhoc.xcconfig"; path = "Pods/Target Support Files/Pods-msgNotificationContent/Pods-msgNotificationContent.distributionadhoc.xcconfig"; sourceTree = "<group>"; };
BE06BDE664323B2A53469696 /* Pods-liblinphoneTesterTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTesterTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTesterTests/Pods-liblinphoneTesterTests.release.xcconfig"; sourceTree = "<group>"; };
C6DA657B261C950C0020CB43 /* VFSUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VFSUtil.swift; sourceTree = "<group>"; };
C90FAA7615AF54E6002091CB /* HistoryDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsView.h; sourceTree = "<group>"; };
C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsView.m; sourceTree = "<group>"; };
C9B3A6FD15B485DB006F52EE /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = Utils/Utils.h; sourceTree = "<group>"; };
...
...
@@ -2126,6 +2128,7 @@
D326483415887D4400930C67 /* Utils */,
34216F3E1547EBCD00EA9777 /* VideoZoomHandler.h */,
34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */,
C6DA657B261C950C0020CB43 /* VFSUtil.swift */,
614C087723D1A35F00217F80 /* ProviderDelegate.swift */,
614C087923D1A37400217F80 /* CallManager.swift */,
EA88F3B0241BDAA100E66528 /* CoreManager.swift */,
...
...
@@ -4235,6 +4238,7 @@
D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */,
63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */,
D3EA53FD159850E80037DC6B /* LinphoneManager.m in Sources */,
C6DA657C261C950C0020CB43 /* VFSUtil.swift in Sources */,
63B81A0E1B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m in Sources */,
633888451BFB2C49001D5E7B /* HPGrowingTextView.m in Sources */,
63F1DF441BCE618E00EDED90 /* UIAddressTextField.m in Sources */,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment