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) {
  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 {
  175      }
  176      catch(chain::wallet_exception&) {
  177         
  178         CFRelease(privateKey);
  179         throw;
  180      }
  183   }
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
 
static public_key_type get_public_key(SecKeyRef key)
 
static string string_for_cferror(CFErrorRef error)