Compare commits
1 Commits
master
...
jrose/type
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4cff38765 |
@ -1,5 +1,7 @@
|
||||
|
||||
class InMemorySignalProtocolStore : IdentityKeyStore, PreKeyStore, SignedPreKeyStore, SessionStore, SenderKeyStore {
|
||||
typealias Context = Void
|
||||
|
||||
private var public_keys : [ProtocolAddress : IdentityKey] = [:]
|
||||
private var private_key : IdentityKeyPair;
|
||||
private var device_id : UInt32;
|
||||
@ -77,10 +79,10 @@ class InMemorySignalProtocolStore : IdentityKeyStore, PreKeyStore, SignedPreKeyS
|
||||
session_map[address] = record;
|
||||
}
|
||||
|
||||
func storeSenderKey(name: SenderKeyName, record: SenderKeyRecord, ctx: UnsafeMutableRawPointer?) throws {
|
||||
func storeSenderKey(name: SenderKeyName, record: SenderKeyRecord, ctx: Void) throws {
|
||||
sender_key_map[name] = record
|
||||
}
|
||||
func loadSenderKey(name: SenderKeyName, ctx: UnsafeMutableRawPointer?) throws -> SenderKeyRecord? {
|
||||
func loadSenderKey(name: SenderKeyName, ctx: Void) throws -> SenderKeyRecord? {
|
||||
return sender_key_map[name]
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,12 @@ enum Direction {
|
||||
case Receiving
|
||||
}
|
||||
|
||||
protocol SignalFfiStore {
|
||||
associatedtype FfiStore
|
||||
associatedtype Context
|
||||
func withFfiStore<Result>(context: Context, _ body: (_ store: UnsafePointer<FfiStore>, _ opaqueContextPointer: UnsafeMutableRawPointer) throws -> Result) rethrows -> Result
|
||||
}
|
||||
|
||||
protocol IdentityKeyStore: AnyObject {
|
||||
func getIdentityKeyPair(ctx: UnsafeMutableRawPointer?) throws -> IdentityKeyPair
|
||||
func getLocalRegistrationId(ctx: UnsafeMutableRawPointer?) throws -> UInt32
|
||||
@ -30,7 +36,21 @@ protocol SessionStore: AnyObject {
|
||||
func storeSession(address: ProtocolAddress, record: SessionRecord, ctx: UnsafeMutableRawPointer?) throws
|
||||
}
|
||||
|
||||
protocol SenderKeyStore: AnyObject {
|
||||
func storeSenderKey(name: SenderKeyName, record: SenderKeyRecord, ctx: UnsafeMutableRawPointer?) throws
|
||||
func loadSenderKey(name: SenderKeyName, ctx: UnsafeMutableRawPointer?) throws -> SenderKeyRecord?
|
||||
protocol AnySenderKeyStore {
|
||||
func _storeSenderKey(name: SenderKeyName, record: SenderKeyRecord, ctx: UnsafeMutableRawPointer?) throws
|
||||
func _loadSenderKey(name: SenderKeyName, ctx: UnsafeMutableRawPointer?) throws -> SenderKeyRecord?
|
||||
}
|
||||
|
||||
protocol SenderKeyStore: AnySenderKeyStore, SignalFfiStore where FfiStore == SignalSenderKeyStore {
|
||||
func storeSenderKey(name: SenderKeyName, record: SenderKeyRecord, ctx: Context) throws
|
||||
func loadSenderKey(name: SenderKeyName, ctx: Context) throws -> SenderKeyRecord?
|
||||
}
|
||||
|
||||
extension SenderKeyStore {
|
||||
func _storeSenderKey(name: SenderKeyName, record: SenderKeyRecord, ctx: UnsafeMutableRawPointer?) throws {
|
||||
try storeSenderKey(name: name, record: record, ctx: ctx!.assumingMemoryBound(to: Context.self).pointee)
|
||||
}
|
||||
func _loadSenderKey(name: SenderKeyName, ctx: UnsafeMutableRawPointer?) throws -> SenderKeyRecord? {
|
||||
return try loadSenderKey(name: name, ctx: ctx!.assumingMemoryBound(to: Context.self).pointee)
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,35 +97,35 @@ func ProcessPreKeyBundle(bundle: PreKeyBundle,
|
||||
}
|
||||
}
|
||||
|
||||
func GroupEncrypt(group_id: SenderKeyName,
|
||||
message: [UInt8],
|
||||
store: SenderKeyStore,
|
||||
ctx: UnsafeMutableRawPointer?) throws -> [UInt8] {
|
||||
return try withSenderKeyStore(store) { ffiStore in
|
||||
func GroupEncrypt<Store: SenderKeyStore>(group_id: SenderKeyName,
|
||||
message: [UInt8],
|
||||
store: Store,
|
||||
ctx: Store.Context) throws -> [UInt8] {
|
||||
return try store.withFfiStore(context: ctx) { ffiStore, ctxPtr in
|
||||
return try invokeFnReturningArray {
|
||||
signal_group_encrypt_message($0, $1, group_id.nativeHandle(), message, message.count, ffiStore, ctx)
|
||||
signal_group_encrypt_message($0, $1, group_id.nativeHandle(), message, message.count, ffiStore, ctxPtr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GroupDecrypt(group_id: SenderKeyName,
|
||||
message: [UInt8],
|
||||
store: SenderKeyStore,
|
||||
ctx: UnsafeMutableRawPointer?) throws -> [UInt8] {
|
||||
return try withSenderKeyStore(store) { ffiStore in
|
||||
func GroupDecrypt<Store: SenderKeyStore>(group_id: SenderKeyName,
|
||||
message: [UInt8],
|
||||
store: Store,
|
||||
ctx: Store.Context) throws -> [UInt8] {
|
||||
return try store.withFfiStore(context: ctx) { ffiStore, ctxPtr in
|
||||
return try invokeFnReturningArray {
|
||||
signal_group_decrypt_message($0, $1, group_id.nativeHandle(), message, message.count, ffiStore, ctx)
|
||||
signal_group_decrypt_message($0, $1, group_id.nativeHandle(), message, message.count, ffiStore, ctxPtr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ProcessSenderKeyDistributionMessage(sender_name: SenderKeyName,
|
||||
msg: SenderKeyDistributionMessage,
|
||||
store: SenderKeyStore,
|
||||
ctx: UnsafeMutableRawPointer?) throws {
|
||||
try withSenderKeyStore(store) {
|
||||
func ProcessSenderKeyDistributionMessage<Store: SenderKeyStore>(sender_name: SenderKeyName,
|
||||
msg: SenderKeyDistributionMessage,
|
||||
store: Store,
|
||||
ctx: Store.Context) throws {
|
||||
try store.withFfiStore(context: ctx) {
|
||||
try CheckError(signal_process_sender_key_distribution_message(sender_name.nativeHandle(),
|
||||
msg.nativeHandle(),
|
||||
$0, ctx))
|
||||
$0, $1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,18 +306,19 @@ func withSessionStore<Result>(_ store: SessionStore, _ body: (UnsafePointer<Sign
|
||||
}
|
||||
}
|
||||
|
||||
func withSenderKeyStore<Result>(_ store: SenderKeyStore, _ body: (UnsafePointer<SignalSenderKeyStore>) throws -> Result) rethrows -> Result {
|
||||
extension SenderKeyStore {
|
||||
func withFfiStore<Result>(context: Context, _ body: (UnsafePointer<SignalSenderKeyStore>, UnsafeMutableRawPointer) throws -> Result) rethrows -> Result {
|
||||
func ffiShimStoreSenderKey(store_ctx: UnsafeMutableRawPointer?,
|
||||
sender_name: OpaquePointer?,
|
||||
record: OpaquePointer?,
|
||||
ctx: UnsafeMutableRawPointer?) -> Int32 {
|
||||
do {
|
||||
let store = store_ctx!.assumingMemoryBound(to: SenderKeyStore.self).pointee
|
||||
let store = store_ctx!.assumingMemoryBound(to: AnySenderKeyStore.self).pointee
|
||||
var sender_name = SenderKeyName(unowned: sender_name)
|
||||
defer { cloneOrForgetAsNeeded(&sender_name) }
|
||||
var record = SenderKeyRecord(unowned: record)
|
||||
defer { cloneOrForgetAsNeeded(&record) }
|
||||
try store.storeSenderKey(name: sender_name, record: record, ctx: ctx)
|
||||
try store._storeSenderKey(name: sender_name, record: record, ctx: ctx)
|
||||
return 0
|
||||
}
|
||||
catch {
|
||||
@ -330,10 +331,10 @@ func withSenderKeyStore<Result>(_ store: SenderKeyStore, _ body: (UnsafePointer<
|
||||
sender_name: OpaquePointer?,
|
||||
ctx: UnsafeMutableRawPointer?) -> Int32 {
|
||||
do {
|
||||
let store = store_ctx!.assumingMemoryBound(to: SenderKeyStore.self).pointee
|
||||
let store = store_ctx!.assumingMemoryBound(to: AnySenderKeyStore.self).pointee
|
||||
var sender_name = SenderKeyName(unowned: sender_name)
|
||||
defer { cloneOrForgetAsNeeded(&sender_name) }
|
||||
if var record = try store.loadSenderKey(name: sender_name, ctx: ctx) {
|
||||
if var record = try store._loadSenderKey(name: sender_name, ctx: ctx) {
|
||||
recordp!.pointee = try cloneOrTakeHandle(from: &record)
|
||||
} else {
|
||||
recordp!.pointee = nil
|
||||
@ -345,13 +346,16 @@ func withSenderKeyStore<Result>(_ store: SenderKeyStore, _ body: (UnsafePointer<
|
||||
}
|
||||
}
|
||||
|
||||
return try withUnsafePointer(to: store) {
|
||||
return try withUnsafePointer(to: self as AnySenderKeyStore) {
|
||||
// We're not actually going to mutate through 'ffiStore.ctx';
|
||||
// it's just the usual convention of `void *` for context fields.
|
||||
var ffiStore = SignalSenderKeyStore(
|
||||
ctx: UnsafeMutableRawPointer(mutating: $0),
|
||||
load_sender_key: ffiShimLoadSenderKey,
|
||||
store_sender_key: ffiShimStoreSenderKey)
|
||||
return try body(&ffiStore)
|
||||
return try withUnsafePointer(to: context) {
|
||||
try body(&ffiStore, UnsafeMutableRawPointer(mutating: $0))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,10 +12,10 @@ class SenderKeyDistributionMessage {
|
||||
return handle
|
||||
}
|
||||
|
||||
init(name: SenderKeyName, store: SenderKeyStore, ctx: UnsafeMutableRawPointer?) throws {
|
||||
try withSenderKeyStore(store) {
|
||||
init<Store: SenderKeyStore>(name: SenderKeyName, store: Store, ctx: Store.Context) throws {
|
||||
try store.withFfiStore(context: ctx) {
|
||||
try CheckError(signal_create_sender_key_distribution_message(&handle, name.nativeHandle(),
|
||||
$0, ctx))
|
||||
$0, $1))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -185,20 +185,20 @@ class SwiftSignalTests: XCTestCase {
|
||||
|
||||
let a_store = try! InMemorySignalProtocolStore()
|
||||
|
||||
let skdm = try! SenderKeyDistributionMessage(name: group_id, store: a_store, ctx: nil)
|
||||
let skdm = try! SenderKeyDistributionMessage(name: group_id, store: a_store, ctx: ())
|
||||
|
||||
let skdm_bits = try! skdm.serialize()
|
||||
|
||||
let skdm_r = try! SenderKeyDistributionMessage(bytes: skdm_bits)
|
||||
|
||||
let a_ctext = try! GroupEncrypt(group_id: group_id, message: [1,2,3], store: a_store, ctx: nil)
|
||||
let a_ctext = try! GroupEncrypt(group_id: group_id, message: [1,2,3], store: a_store, ctx: ())
|
||||
|
||||
let b_store = try! InMemorySignalProtocolStore()
|
||||
try! ProcessSenderKeyDistributionMessage(sender_name: group_id,
|
||||
msg: skdm_r,
|
||||
store: b_store,
|
||||
ctx: nil)
|
||||
let b_ptext = try! GroupDecrypt(group_id: group_id, message: a_ctext, store: b_store, ctx: nil)
|
||||
ctx: ())
|
||||
let b_ptext = try! GroupDecrypt(group_id: group_id, message: a_ctext, store: b_store, ctx: ())
|
||||
|
||||
XCTAssertEqual(b_ptext, [1,2,3])
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user