Build secure Rust watchOS TOTP core (#56)

This commit is contained in:
2026-08-16 14:27:21 +02:00
parent a055c93b86
commit df1d49339c
20 changed files with 2672 additions and 137 deletions

View File

@@ -0,0 +1,7 @@
module ironstorage_watch {
header "ironstorage_watchFFI.h"
export *
use "Darwin"
use "_Builtin_stdbool"
use "_Builtin_stdint"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,578 @@
// This file was autogenerated by some hot garbage in the `uniffi` crate.
// Trust me, you don't want to mess with it!
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
// The following structs are used to implement the lowest level
// of the FFI, and thus useful to multiple uniffied crates.
// We ensure they are declared exactly once, with a header guard, UNIFFI_SHARED_H.
#ifdef UNIFFI_SHARED_H
// We also try to prevent mixing versions of shared uniffi header structs.
// If you add anything to the #else block, you must increment the version suffix in UNIFFI_SHARED_HEADER_V4
#ifndef UNIFFI_SHARED_HEADER_V4
#error Combining helper code from multiple versions of uniffi is not supported
#endif // ndef UNIFFI_SHARED_HEADER_V4
#else
#define UNIFFI_SHARED_H
#define UNIFFI_SHARED_HEADER_V4
// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️
// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️
typedef struct RustBuffer
{
uint64_t capacity;
uint64_t len;
uint8_t *_Nullable data;
} RustBuffer;
typedef struct ForeignBytes
{
int32_t len;
const uint8_t *_Nullable data;
} ForeignBytes;
// Error definitions
typedef struct RustCallStatus {
int8_t code;
RustBuffer errorBuf;
} RustCallStatus;
// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️
// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️
#endif // def UNIFFI_SHARED_H
#ifndef UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK
#define UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK
typedef void (*UniffiRustFutureContinuationCallback)(uint64_t, int8_t
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK
typedef void (*UniffiForeignFutureDroppedCallback)(uint64_t
);
#endif
#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE
#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE
typedef void (*UniffiCallbackInterfaceFree)(uint64_t
);
#endif
#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_CLONE
#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_CLONE
typedef uint64_t (*UniffiCallbackInterfaceClone)(uint64_t
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK_STRUCT
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_DROPPED_CALLBACK_STRUCT
typedef struct UniffiForeignFutureDroppedCallbackStruct {
uint64_t handle;
UniffiForeignFutureDroppedCallback _Nonnull free;
} UniffiForeignFutureDroppedCallbackStruct;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U8
typedef struct UniffiForeignFutureResultU8 {
uint8_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultU8;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8
typedef void (*UniffiForeignFutureCompleteU8)(uint64_t, UniffiForeignFutureResultU8
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I8
typedef struct UniffiForeignFutureResultI8 {
int8_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultI8;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8
typedef void (*UniffiForeignFutureCompleteI8)(uint64_t, UniffiForeignFutureResultI8
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U16
typedef struct UniffiForeignFutureResultU16 {
uint16_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultU16;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16
typedef void (*UniffiForeignFutureCompleteU16)(uint64_t, UniffiForeignFutureResultU16
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I16
typedef struct UniffiForeignFutureResultI16 {
int16_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultI16;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16
typedef void (*UniffiForeignFutureCompleteI16)(uint64_t, UniffiForeignFutureResultI16
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U32
typedef struct UniffiForeignFutureResultU32 {
uint32_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultU32;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32
typedef void (*UniffiForeignFutureCompleteU32)(uint64_t, UniffiForeignFutureResultU32
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I32
typedef struct UniffiForeignFutureResultI32 {
int32_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultI32;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32
typedef void (*UniffiForeignFutureCompleteI32)(uint64_t, UniffiForeignFutureResultI32
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_U64
typedef struct UniffiForeignFutureResultU64 {
uint64_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultU64;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64
typedef void (*UniffiForeignFutureCompleteU64)(uint64_t, UniffiForeignFutureResultU64
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_I64
typedef struct UniffiForeignFutureResultI64 {
int64_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultI64;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64
typedef void (*UniffiForeignFutureCompleteI64)(uint64_t, UniffiForeignFutureResultI64
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F32
typedef struct UniffiForeignFutureResultF32 {
float returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultF32;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32
typedef void (*UniffiForeignFutureCompleteF32)(uint64_t, UniffiForeignFutureResultF32
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_F64
typedef struct UniffiForeignFutureResultF64 {
double returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultF64;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64
typedef void (*UniffiForeignFutureCompleteF64)(uint64_t, UniffiForeignFutureResultF64
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_RUST_BUFFER
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_RUST_BUFFER
typedef struct UniffiForeignFutureResultRustBuffer {
RustBuffer returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureResultRustBuffer;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER
typedef void (*UniffiForeignFutureCompleteRustBuffer)(uint64_t, UniffiForeignFutureResultRustBuffer
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_VOID
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_RESULT_VOID
typedef struct UniffiForeignFutureResultVoid {
RustCallStatus callStatus;
} UniffiForeignFutureResultVoid;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID
typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t, UniffiForeignFutureResultVoid
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_CLONE_WATCHCORE
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_CLONE_WATCHCORE
uint64_t uniffi_ironstorage_watch_fn_clone_watchcore(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_FREE_WATCHCORE
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_FREE_WATCHCORE
void uniffi_ironstorage_watch_fn_free_watchcore(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_APPLY_SNAPSHOT
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_APPLY_SNAPSHOT
RustBuffer uniffi_ironstorage_watch_fn_method_watchcore_apply_snapshot(uint64_t ptr, RustBuffer snapshot, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_NO_PERSISTED_SNAPSHOT
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_NO_PERSISTED_SNAPSHOT
void uniffi_ironstorage_watch_fn_method_watchcore_no_persisted_snapshot(uint64_t ptr, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_PROTECTED_DATA_UNAVAILABLE
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_PROTECTED_DATA_UNAVAILABLE
void uniffi_ironstorage_watch_fn_method_watchcore_protected_data_unavailable(uint64_t ptr, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_RECORDS_AT
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_METHOD_WATCHCORE_RECORDS_AT
RustBuffer uniffi_ironstorage_watch_fn_method_watchcore_records_at(uint64_t ptr, uint64_t unix_seconds, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_FUNC_WATCH_CORE
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_FN_FUNC_WATCH_CORE
uint64_t uniffi_ironstorage_watch_fn_func_watch_core(RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_ALLOC
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_ALLOC
RustBuffer ffi_ironstorage_watch_rustbuffer_alloc(uint64_t size, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_FROM_BYTES
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_FROM_BYTES
RustBuffer ffi_ironstorage_watch_rustbuffer_from_bytes(ForeignBytes bytes, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_FREE
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_FREE
void ffi_ironstorage_watch_rustbuffer_free(RustBuffer buf, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_RESERVE
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUSTBUFFER_RESERVE
RustBuffer ffi_ironstorage_watch_rustbuffer_reserve(RustBuffer buf, uint64_t additional, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U8
void ffi_ironstorage_watch_rust_future_poll_u8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U8
void ffi_ironstorage_watch_rust_future_cancel_u8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U8
void ffi_ironstorage_watch_rust_future_free_u8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U8
uint8_t ffi_ironstorage_watch_rust_future_complete_u8(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I8
void ffi_ironstorage_watch_rust_future_poll_i8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I8
void ffi_ironstorage_watch_rust_future_cancel_i8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I8
void ffi_ironstorage_watch_rust_future_free_i8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I8
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I8
int8_t ffi_ironstorage_watch_rust_future_complete_i8(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U16
void ffi_ironstorage_watch_rust_future_poll_u16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U16
void ffi_ironstorage_watch_rust_future_cancel_u16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U16
void ffi_ironstorage_watch_rust_future_free_u16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U16
uint16_t ffi_ironstorage_watch_rust_future_complete_u16(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I16
void ffi_ironstorage_watch_rust_future_poll_i16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I16
void ffi_ironstorage_watch_rust_future_cancel_i16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I16
void ffi_ironstorage_watch_rust_future_free_i16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I16
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I16
int16_t ffi_ironstorage_watch_rust_future_complete_i16(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U32
void ffi_ironstorage_watch_rust_future_poll_u32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U32
void ffi_ironstorage_watch_rust_future_cancel_u32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U32
void ffi_ironstorage_watch_rust_future_free_u32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U32
uint32_t ffi_ironstorage_watch_rust_future_complete_u32(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I32
void ffi_ironstorage_watch_rust_future_poll_i32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I32
void ffi_ironstorage_watch_rust_future_cancel_i32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I32
void ffi_ironstorage_watch_rust_future_free_i32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I32
int32_t ffi_ironstorage_watch_rust_future_complete_i32(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_U64
void ffi_ironstorage_watch_rust_future_poll_u64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_U64
void ffi_ironstorage_watch_rust_future_cancel_u64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_U64
void ffi_ironstorage_watch_rust_future_free_u64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_U64
uint64_t ffi_ironstorage_watch_rust_future_complete_u64(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_I64
void ffi_ironstorage_watch_rust_future_poll_i64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_I64
void ffi_ironstorage_watch_rust_future_cancel_i64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_I64
void ffi_ironstorage_watch_rust_future_free_i64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_I64
int64_t ffi_ironstorage_watch_rust_future_complete_i64(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_F32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_F32
void ffi_ironstorage_watch_rust_future_poll_f32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_F32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_F32
void ffi_ironstorage_watch_rust_future_cancel_f32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_F32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_F32
void ffi_ironstorage_watch_rust_future_free_f32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_F32
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_F32
float ffi_ironstorage_watch_rust_future_complete_f32(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_F64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_F64
void ffi_ironstorage_watch_rust_future_poll_f64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_F64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_F64
void ffi_ironstorage_watch_rust_future_cancel_f64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_F64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_F64
void ffi_ironstorage_watch_rust_future_free_f64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_F64
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_F64
double ffi_ironstorage_watch_rust_future_complete_f64(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_RUST_BUFFER
void ffi_ironstorage_watch_rust_future_poll_rust_buffer(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_RUST_BUFFER
void ffi_ironstorage_watch_rust_future_cancel_rust_buffer(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_RUST_BUFFER
void ffi_ironstorage_watch_rust_future_free_rust_buffer(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_RUST_BUFFER
RustBuffer ffi_ironstorage_watch_rust_future_complete_rust_buffer(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_VOID
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_POLL_VOID
void ffi_ironstorage_watch_rust_future_poll_void(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_VOID
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_CANCEL_VOID
void ffi_ironstorage_watch_rust_future_cancel_void(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_VOID
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_FREE_VOID
void ffi_ironstorage_watch_rust_future_free_void(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_VOID
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_RUST_FUTURE_COMPLETE_VOID
void ffi_ironstorage_watch_rust_future_complete_void(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_FUNC_WATCH_CORE
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_FUNC_WATCH_CORE
uint16_t uniffi_ironstorage_watch_checksum_func_watch_core(void
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_APPLY_SNAPSHOT
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_APPLY_SNAPSHOT
uint16_t uniffi_ironstorage_watch_checksum_method_watchcore_apply_snapshot(void
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_NO_PERSISTED_SNAPSHOT
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_NO_PERSISTED_SNAPSHOT
uint16_t uniffi_ironstorage_watch_checksum_method_watchcore_no_persisted_snapshot(void
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_PROTECTED_DATA_UNAVAILABLE
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_PROTECTED_DATA_UNAVAILABLE
uint16_t uniffi_ironstorage_watch_checksum_method_watchcore_protected_data_unavailable(void
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_RECORDS_AT
#define UNIFFI_FFIDEF_UNIFFI_IRONSTORAGE_WATCH_CHECKSUM_METHOD_WATCHCORE_RECORDS_AT
uint16_t uniffi_ironstorage_watch_checksum_method_watchcore_records_at(void
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_UNIFFI_CONTRACT_VERSION
#define UNIFFI_FFIDEF_FFI_IRONSTORAGE_WATCH_UNIFFI_CONTRACT_VERSION
uint32_t ffi_ironstorage_watch_uniffi_contract_version(void
);
#endif

View File

@@ -0,0 +1 @@
#include "Generated/ironstorage_watchFFI.h"

View File

@@ -1,57 +1,177 @@
import Security
import SwiftUI
import WatchConnectivity
private enum SecureSnapshotStore {
private static let service = "de.rfc1437.ironstorage.watch.snapshot"
private static let account = "selected-totp"
static func load() throws -> Data? {
var result: CFTypeRef?
let status = SecItemCopyMatching([
kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecReturnData: true,
kSecMatchLimit: kSecMatchLimitOne,
] as CFDictionary, &result)
if status == errSecItemNotFound { return nil }
guard status == errSecSuccess, let data = result as? Data else {
throw SnapshotStoreError(status: status)
}
return data
}
static func replace(_ snapshot: Data) throws {
let query = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
] as CFDictionary
let status = SecItemUpdate(query, [kSecValueData: snapshot] as CFDictionary)
if status == errSecItemNotFound {
let added = SecItemAdd([
kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecValueData: snapshot,
kSecAttrAccessible: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
] as CFDictionary, nil)
guard added == errSecSuccess else { throw SnapshotStoreError(status: added) }
} else if status != errSecSuccess {
throw SnapshotStoreError(status: status)
}
}
static func delete() throws {
let status = SecItemDelete([
kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
] as CFDictionary)
guard status == errSecSuccess || status == errSecItemNotFound else {
throw SnapshotStoreError(status: status)
}
}
}
private struct SnapshotStoreError: Error {
let status: OSStatus
}
@MainActor
private final class WatchSnapshotTransport: NSObject, ObservableObject, WCSessionDelegate {
private static let snapshotKey = "de.rfc1437.ironstorage.watch.snapshot"
private static let deliveredReceiptKey = "de.rfc1437.ironstorage.watch.delivered"
private static let receiptKey = "de.rfc1437.ironstorage.watch.delivered"
@Published private(set) var records: [WatchTotpRecord] = []
private let core = watchCore()
override init() {
super.init()
restoreSnapshot()
guard WCSession.isSupported() else { return }
let session = WCSession.default
session.delegate = self
session.activate()
}
private func receive(_ applicationContext: [String: Any], session: WCSession) {
guard
applicationContext[Self.snapshotKey] is Data,
let receipt = applicationContext[Self.deliveredReceiptKey] as? Data
else { return }
let acknowledgement = [Self.deliveredReceiptKey: receipt]
if session.isReachable {
session.sendMessage(acknowledgement, replyHandler: nil) { _ in
session.transferUserInfo(acknowledgement)
func sceneBecameActive() {
restoreSnapshot()
}
func sceneBecameInactive() {
try? core.protectedDataUnavailable()
records.removeAll(keepingCapacity: false)
}
private func restoreSnapshot() {
do {
if var snapshot = try SecureSnapshotStore.load() {
defer { snapshot.resetBytes(in: 0..<snapshot.count) }
let update = try core.applySnapshot(snapshot: snapshot)
if update.persistence == .delete { try SecureSnapshotStore.delete() }
} else {
try core.noPersistedSnapshot()
}
} else {
session.transferUserInfo(acknowledgement)
refreshRecords()
} catch {
try? core.protectedDataUnavailable()
records.removeAll(keepingCapacity: false)
}
}
func session(
private func receive(_ applicationContext: [String: Any], session: WCSession) {
guard var snapshot = applicationContext[Self.snapshotKey] as? Data else { return }
defer { snapshot.resetBytes(in: 0..<snapshot.count) }
do {
let update = try core.applySnapshot(snapshot: snapshot)
switch update.persistence {
case .keep:
break
case .replace:
try SecureSnapshotStore.replace(snapshot)
case .delete:
try SecureSnapshotStore.delete()
}
refreshRecords()
guard !update.receipt.isEmpty else { return }
let acknowledgement = [Self.receiptKey: update.receipt]
if session.isReachable {
session.sendMessage(acknowledgement, replyHandler: nil) { _ in
session.transferUserInfo(acknowledgement)
}
} else {
session.transferUserInfo(acknowledgement)
}
} catch {
try? core.noPersistedSnapshot()
records.removeAll(keepingCapacity: false)
}
}
private func refreshRecords() {
records = (try? core.recordsAt(
unixSeconds: UInt64(Date().timeIntervalSince1970)
)) ?? []
}
nonisolated func session(
_ session: WCSession,
activationDidCompleteWith activationState: WCSessionActivationState,
error: Error?
) {
guard activationState == .activated, error == nil else { return }
receive(session.receivedApplicationContext, session: session)
Task { @MainActor [weak self] in
self?.receive(session.receivedApplicationContext, session: session)
}
}
func session(
nonisolated func session(
_ session: WCSession,
didReceiveApplicationContext applicationContext: [String: Any]
) {
receive(applicationContext, session: session)
Task { @MainActor [weak self] in
self?.receive(applicationContext, session: session)
}
}
}
@main
struct IronStorageWatchApp: App {
@Environment(\.scenePhase) private var scenePhase
@StateObject private var transport = WatchSnapshotTransport()
var body: some Scene {
WindowGroup {
ContentUnavailableView("No TOTP Codes", systemImage: "timer")
.onChange(of: scenePhase) { _, phase in
if phase == .active {
transport.sceneBecameActive()
} else {
transport.sceneBecameInactive()
}
}
}
}
}

View File

@@ -11,28 +11,42 @@ else
profile=release
fi
if [[ "${PLATFORM_NAME:-}" == watch* ]]; then
package=ironstorage-watch-apple
library=ironstorage_watch
else
package=ironstorage-apple
library=ironstorage_apple
fi
libraries=()
for arch in $ARCHS; do
if [[ "$arch" == "arm64" && "${LLVM_TARGET_TRIPLE_SUFFIX:-}" == "-simulator" ]]; then
if [[ "$package" == "ironstorage-watch-apple" && "$arch" == "arm64" && "${LLVM_TARGET_TRIPLE_SUFFIX:-}" == "-simulator" ]]; then
target=aarch64-apple-watchos-sim
elif [[ "$package" == "ironstorage-watch-apple" && "$arch" == "arm64" ]]; then
target=aarch64-apple-watchos
elif [[ "$package" == "ironstorage-watch-apple" && "$arch" == "x86_64" ]]; then
target=x86_64-apple-watchos-sim
elif [[ "$arch" == "arm64" && "${LLVM_TARGET_TRIPLE_SUFFIX:-}" == "-simulator" ]]; then
target=aarch64-apple-ios-sim
elif [[ "$arch" == "arm64" ]]; then
target=aarch64-apple-ios
elif [[ "$arch" == "x86_64" ]]; then
target=x86_64-apple-ios
else
echo "Unsupported iOS architecture: $arch" >&2
echo "Unsupported ${PLATFORM_NAME:-Apple} architecture: $arch" >&2
exit 1
fi
if [[ "$profile" == "debug" ]]; then
rustup run stable cargo build --locked \
--target "$target" --package ironstorage-apple --lib
--target "$target" --package "$package" --lib
else
rustup run stable cargo build --locked --release \
--target "$target" --package ironstorage-apple --lib
--target "$target" --package "$package" --lib
fi
libraries+=("$CARGO_TARGET_DIR/$target/$profile/libironstorage_apple.a")
libraries+=("$CARGO_TARGET_DIR/$target/$profile/lib$library.a")
done
mkdir -p "$DERIVED_FILE_DIR/rust"
lipo -create -output "$DERIVED_FILE_DIR/rust/libironstorage_apple.a" "${libraries[@]}"
lipo -create -output "$DERIVED_FILE_DIR/rust/lib$library.a" "${libraries[@]}"

View File

@@ -77,6 +77,10 @@ targets:
PRODUCT_BUNDLE_IDENTIFIER: de.rfc1437.ironstorage.watch
PRODUCT_NAME: IronStorage Watch
SKIP_INSTALL: YES
"EXCLUDED_ARCHS[sdk=watchsimulator*]": x86_64
SWIFT_OBJC_BRIDGING_HEADER: IronStorage-Watch-Bridging-Header.h
LIBRARY_SEARCH_PATHS: "$(inherited) $(DERIVED_FILE_DIR)/rust"
OTHER_LDFLAGS: "$(inherited) -lironstorage_watch"
info:
path: Watch-Info.plist
properties:
@@ -86,3 +90,11 @@ targets:
sources:
- Assets.xcassets
- Sources/Watch
- Generated/ironstorage_watch.swift
preBuildScripts:
- name: Build Rust Watch core
basedOnDependencyAnalysis: false
script: |
./build_rust_core.bash
outputFiles:
- $(DERIVED_FILE_DIR)/rust/libironstorage_watch.a