Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::wallet::detail::se_wallet_impl Struct Reference
Collaboration diagram for sysio::wallet::detail::se_wallet_impl:

Public Member Functions

void populate_existing_keys ()
 
public_key_type create ()
 
std::optional< signature_typetry_sign_digest (const digest_type d, const public_key_type public_key)
 
bool remove_key (string public_key)
 
 ~se_wallet_impl ()
 

Static Public Member Functions

static public_key_data get_public_key_data (SecKeyRef key)
 
static public_key_type get_public_key (SecKeyRef key)
 
static string string_for_cferror (CFErrorRef error)
 

Public Attributes

map< public_key_type, SecKeyRef > _keys
 
fc::ec_key key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)
 
bool locked = true
 

Detailed Description

Definition at line 25 of file se_wallet.cpp.

Constructor & Destructor Documentation

◆ ~se_wallet_impl()

sysio::wallet::detail::se_wallet_impl::~se_wallet_impl ( )
inline

Definition at line 255 of file se_wallet.cpp.

255 {
256 for(auto& k : _keys)
257 CFRelease(k.second);
258 }
map< public_key_type, SecKeyRef > _keys

Member Function Documentation

◆ create()

public_key_type sysio::wallet::detail::se_wallet_impl::create ( )
inline

Definition at line 122 of file se_wallet.cpp.

122 {
123 SecAccessControlRef accessControlRef = SecAccessControlCreateWithFlags(nullptr, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kSecAccessControlPrivateKeyUsage, nullptr);
124
125 int keySizeValue = 256;
126 CFNumberRef keySizeNumber = CFNumberCreate(NULL, kCFNumberIntType, &keySizeValue);
127
128 const void* keyAttrKeys[] = {
129 kSecAttrIsPermanent,
130 kSecAttrAccessControl,
131 kSecAttrAccessGroup
132 };
133 const void* keyAttrValues[] = {
134 kCFBooleanTrue,
135 accessControlRef,
136#ifdef MAS_KEYCHAIN_GROUP
137 CFSTR(XSTR(MAS_KEYCHAIN_GROUP))
138#endif
139 };
140 CFDictionaryRef keyAttrDic = CFDictionaryCreate(NULL, keyAttrKeys, keyAttrValues, sizeof(keyAttrValues)/sizeof(keyAttrValues[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
141
142 const void* attrKeys[] = {
143 kSecAttrKeyType,
144 kSecAttrKeySizeInBits,
145 kSecAttrTokenID,
146 kSecPrivateKeyAttrs
147 };
148 const void* atrrValues[] = {
149 kSecAttrKeyTypeECSECPrimeRandom,
150 keySizeNumber,
151 kSecAttrTokenIDSecureEnclave,
152 keyAttrDic
153 };
154 CFDictionaryRef attributesDic = CFDictionaryCreate(NULL, attrKeys, atrrValues, sizeof(attrKeys)/sizeof(attrKeys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
155
156 CFErrorRef error = NULL;
157 SecKeyRef privateKey = SecKeyCreateRandomKey(attributesDic, &error);
158 string error_string;
159 if(error) {
160 error_string = string_for_cferror(error);
161 CFRelease(error);
162 }
163
164 CFRelease(attributesDic);
165 CFRelease(keyAttrDic);
166 CFRelease(keySizeNumber);
167 CFRelease(accessControlRef);
168
169 if(error_string.size())
170 FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to create key in Secure Enclave: ${m}", ("m", error_string));
171
173 try {
174 pub = get_public_key(privateKey);
175 }
176 catch(chain::wallet_exception&) {
177 //possibly we should delete the key here?
178 CFRelease(privateKey);
179 throw;
180 }
181 _keys[pub] = privateKey;
182 return pub;
183 }
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
#define XSTR(A)
Definition se_wallet.cpp:79
static public_key_type get_public_key(SecKeyRef key)
Definition se_wallet.cpp:53
static string string_for_cferror(CFErrorRef error)
Definition se_wallet.cpp:67
bool pub
Here is the call graph for this function:

◆ get_public_key()

static public_key_type sysio::wallet::detail::se_wallet_impl::get_public_key ( SecKeyRef key)
inlinestatic

Definition at line 53 of file se_wallet.cpp.

53 {
54 char serialized_pub_key[sizeof(public_key_data) + 1];
55 serialized_pub_key[0] = 0x01;
56
57 public_key_data pub_key_data = get_public_key_data(key);
58 memcpy(serialized_pub_key+1, pub_key_data.data, sizeof(pub_key_data));
59
60 public_key_type pub_key;
61 fc::datastream<const char *> ds(serialized_pub_key, sizeof(serialized_pub_key));
62 fc::raw::unpack(ds, pub_key);
63
64 return pub_key;
65 }
static const Segment ds(Segment::ds)
fc::array< char, 33 > public_key_data
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
static public_key_data get_public_key_data(SecKeyRef key)
Definition se_wallet.cpp:27
memcpy((char *) pInfo->slotDescription, s, l)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_public_key_data()

static public_key_data sysio::wallet::detail::se_wallet_impl::get_public_key_data ( SecKeyRef key)
inlinestatic

Definition at line 27 of file se_wallet.cpp.

27 {
28 SecKeyRef pubkey = SecKeyCopyPublicKey(key);
29
30 CFErrorRef error = nullptr;
31 CFDataRef keyrep = nullptr;
32 keyrep = SecKeyCopyExternalRepresentation(pubkey, &error);
33
34 public_key_data pub_key_data;
35 if(!error) {
36 const UInt8* cfdata = CFDataGetBytePtr(keyrep);
37 memcpy(pub_key_data.data+1, cfdata+1, 32);
38 pub_key_data.data[0] = 0x02 + (cfdata[64]&1);
39 }
40
41 CFRelease(keyrep);
42 CFRelease(pubkey);
43
44 if(error) {
45 string error_string = string_for_cferror(error);
46 CFRelease(error);
47 FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to get public key from Secure Enclave: ${m}", ("m", error_string));
48 }
49
50 return pub_key_data;
51 }
CK_BYTE_PTR pubkey
Here is the call graph for this function:
Here is the caller graph for this function:

◆ populate_existing_keys()

void sysio::wallet::detail::se_wallet_impl::populate_existing_keys ( )
inline

Definition at line 82 of file se_wallet.cpp.

82 {
83 const void* keyAttrKeys[] = {
84 kSecClass,
85 kSecAttrKeyClass,
86 kSecMatchLimit,
87 kSecReturnRef,
88 kSecAttrTokenID,
89 kSecAttrAccessGroup
90 };
91 const void* keyAttrValues[] = {
92 kSecClassKey,
93 kSecAttrKeyClassPrivate,
94 kSecMatchLimitAll,
95 kCFBooleanTrue,
96 kSecAttrTokenIDSecureEnclave,
97#ifdef MAS_KEYCHAIN_GROUP
98 CFSTR(XSTR(MAS_KEYCHAIN_GROUP))
99#endif
100 };
101 CFDictionaryRef keyAttrDic = CFDictionaryCreate(nullptr, keyAttrKeys, keyAttrValues, sizeof(keyAttrValues)/sizeof(keyAttrValues[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
102
103 CFArrayRef keyRefs = nullptr;
104 if(SecItemCopyMatching(keyAttrDic, (CFTypeRef*)&keyRefs) || !keyRefs) {
105 CFRelease(keyAttrDic);
106 return;
107 }
108
109 CFIndex count = CFArrayGetCount(keyRefs);
110 for(long i = 0; i < count; ++i) {
112 try {
113 SecKeyRef key = (SecKeyRef)CFRetain(CFArrayGetValueAtIndex(keyRefs, i));
114 _keys[get_public_key(key)] = key;
115 }
116 catch(chain::wallet_exception&) {}
117 }
118 CFRelease(keyRefs);
119 CFRelease(keyAttrDic);
120 }
int * count
Here is the call graph for this function:

◆ remove_key()

bool sysio::wallet::detail::se_wallet_impl::remove_key ( string public_key)
inline

Definition at line 230 of file se_wallet.cpp.

230 {
231 auto it = _keys.find(public_key_type{public_key});
232 if(it == _keys.end())
233 FC_THROW_EXCEPTION(chain::wallet_exception, "Given key to delete not found in Secure Enclave wallet");
234
235 promise<bool> prom;
236 future<bool> fut = prom.get_future();
237 macos_user_auth(auth_callback, &prom, CFSTR("remove a key from your SYSIO wallet"));
238 if(!fut.get())
239 FC_THROW_EXCEPTION(chain::wallet_invalid_password_exception, "Local user authentication failed");
240
241 CFDictionaryRef deleteDic = CFDictionaryCreate(nullptr, (const void**)&kSecValueRef, (const void**)&it->second, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
242
243 OSStatus ret = SecItemDelete(deleteDic);
244 CFRelease(deleteDic);
245
246 if(ret)
247 FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to getremove key from Secure Enclave");
248
249 CFRelease(it->second);
250 _keys.erase(it);
251
252 return true;
253 }
void macos_user_auth(void(*cb)(int, void *), void *cb_userdata, CFStringRef message)
CK_RV ret
Here is the call graph for this function:

◆ string_for_cferror()

static string sysio::wallet::detail::se_wallet_impl::string_for_cferror ( CFErrorRef error)
inlinestatic

Definition at line 67 of file se_wallet.cpp.

67 {
68 CFStringRef errorString = CFCopyDescription(error);
69 char buff[CFStringGetLength(errorString) + 1];
70 string ret;
71 if(CFStringGetCString(errorString, buff, sizeof(buff), kCFStringEncodingUTF8))
72 ret = buff;
73 else
74 ret = "Unknown";
75 CFRelease(errorString);
76 return ret;
77 }
Here is the caller graph for this function:

◆ try_sign_digest()

std::optional< signature_type > sysio::wallet::detail::se_wallet_impl::try_sign_digest ( const digest_type d,
const public_key_type public_key )
inline

Definition at line 185 of file se_wallet.cpp.

185 {
186 auto it = _keys.find(public_key);
187 if(it == _keys.end())
188 return std::optional<signature_type>{};
189
190 fc::ecdsa_sig sig = ECDSA_SIG_new();
191 CFErrorRef error = nullptr;
192
193 CFDataRef digestData = CFDataCreateWithBytesNoCopy(nullptr, (UInt8*)d.data(), d.data_size(), kCFAllocatorNull);
194 CFDataRef signature = SecKeyCreateSignature(it->second, kSecKeyAlgorithmECDSASignatureDigestX962SHA256, digestData, &error);
195 if(error) {
196 string error_string = string_for_cferror(error);
197 CFRelease(error);
198 CFRelease(digestData);
199 FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to sign digest in Secure Enclave: ${m}", ("m", error_string));
200 }
201
202 const UInt8* der_bytes = CFDataGetBytePtr(signature);
203 long derSize = CFDataGetLength(signature);
204 d2i_ECDSA_SIG(&sig.obj, &der_bytes, derSize);
205
207 compact_signature compact_sig;
208 try {
209 kd = get_public_key_data(it->second);
210 compact_sig = signature_from_ecdsa(key, kd, sig, d);
211 } catch(chain::wallet_exception&) {
212 CFRelease(signature);
213 CFRelease(digestData);
214 throw;
215 }
216
217 CFRelease(signature);
218 CFRelease(digestData);
219
220 char serialized_signature[sizeof(compact_sig) + 1];
221 serialized_signature[0] = 0x01;
222 memcpy(serialized_signature+1, compact_sig.data, sizeof(compact_sig));
223
224 signature_type final_signature;
225 fc::datastream<const char *> ds(serialized_signature, sizeof(serialized_signature));
226 fc::raw::unpack(ds, final_signature);
227 return final_signature;
228 }
compact_signature signature_from_ecdsa(const EC_KEY *key, const public_key_data &pub, fc::ecdsa_sig &sig, const fc::sha256 &d)
fc::array< unsigned char, 65 > compact_signature
bytes signature
Definition pke.hpp:17
CK_ULONG d
Here is the call graph for this function:

Member Data Documentation

◆ _keys

map<public_key_type,SecKeyRef> sysio::wallet::detail::se_wallet_impl::_keys

Definition at line 260 of file se_wallet.cpp.

◆ key

fc::ec_key sysio::wallet::detail::se_wallet_impl::key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)

Definition at line 261 of file se_wallet.cpp.

◆ locked

bool sysio::wallet::detail::se_wallet_impl::locked = true

Definition at line 262 of file se_wallet.cpp.


The documentation for this struct was generated from the following file: