void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage usage, std::unique_ptr<PromiseWrapper> promise) { uint32_t e; if (!bigIntegerToUInt32(publicExponent, e)) { // Adding support is tracked as <rdar://problem/15444034>. WTFLogAlways("Public exponent is too big, not supported"); promise->reject(nullptr); return; } PromiseWrapper* localPromise = promise.release(); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ CCRSACryptorRef ccPublicKey; CCRSACryptorRef ccPrivateKey; CCCryptorStatus status = CCRSACryptorGeneratePair(modulusLength, e, &ccPublicKey, &ccPrivateKey); if (status) { WTFLogAlways("Could not generate a key pair, status %d", status); dispatch_async(dispatch_get_main_queue(), ^{ localPromise->reject(nullptr); delete localPromise; }); return; } dispatch_async(dispatch_get_main_queue(), ^{ RefPtr<CryptoKeyRSA> publicKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Public, ccPublicKey, extractable, usage); RefPtr<CryptoKeyRSA> privateKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Private, ccPrivateKey, extractable, usage); localPromise->fulfill(CryptoKeyPair::create(publicKey.release(), privateKey.release())); delete localPromise; });
void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage usage, KeyPairCallback callback, VoidCallback failureCallback) { uint32_t e; if (!bigIntegerToUInt32(publicExponent, e)) { // Adding support is tracked as <rdar://problem/15444034>. WTFLogAlways("Public exponent is too big, not supported"); failureCallback(); return; } // We only use the callback functions when back on the main thread, but captured variables are copied on a secondary thread too. KeyPairCallback* localCallback = new KeyPairCallback(WTF::move(callback)); VoidCallback* localFailureCallback = new VoidCallback(WTF::move(failureCallback)); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ CCRSACryptorRef ccPublicKey; CCRSACryptorRef ccPrivateKey; CCCryptorStatus status = CCRSACryptorGeneratePair(modulusLength, e, &ccPublicKey, &ccPrivateKey); if (status) { WTFLogAlways("Could not generate a key pair, status %d", status); callOnWebThreadOrDispatchAsyncOnMainThread(^{ (*localFailureCallback)(); delete localFailureCallback; }); return; } callOnWebThreadOrDispatchAsyncOnMainThread(^{ RefPtr<CryptoKeyRSA> publicKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Public, ccPublicKey, true, usage); RefPtr<CryptoKeyRSA> privateKey = CryptoKeyRSA::create(algorithm, CryptoKeyType::Private, ccPrivateKey, extractable, usage); (*localCallback)(CryptoKeyPair::create(publicKey.release(), privateKey.release())); delete localCallback; });
// FIXME: We should use WorkQueue here instead of dispatch_async once WebKitSubtleCrypto is deprecated. // https://bugs.webkit.org/show_bug.cgi?id=164943 void CryptoKeyRSA::generatePair(CryptoAlgorithmIdentifier algorithm, CryptoAlgorithmIdentifier hash, bool hasHash, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsageBitmap usage, KeyPairCallback&& callback, VoidCallback&& failureCallback, ScriptExecutionContext* context) { uint32_t e; if (!bigIntegerToUInt32(publicExponent, e)) { // Adding support is tracked as <rdar://problem/15444034>. WTFLogAlways("Public exponent is too big, not supported"); failureCallback(); return; } // We only use the callback functions when back on the main/worker thread, but captured variables are copied on a secondary thread too. KeyPairCallback* localCallback = new KeyPairCallback(WTFMove(callback)); VoidCallback* localFailureCallback = new VoidCallback(WTFMove(failureCallback)); context->ref(); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ ASSERT(context); CCRSACryptorRef ccPublicKey; CCRSACryptorRef ccPrivateKey; CCCryptorStatus status = CCRSACryptorGeneratePair(modulusLength, e, &ccPublicKey, &ccPrivateKey); if (status) { WTFLogAlways("Could not generate a key pair, status %d", status); context->postTask([localCallback, localFailureCallback](ScriptExecutionContext& context) { (*localFailureCallback)(); delete localCallback; delete localFailureCallback; context.deref(); }); return; } context->postTask([algorithm, hash, hasHash, extractable, usage, localCallback, localFailureCallback, ccPublicKey, ccPrivateKey](ScriptExecutionContext& context) { auto publicKey = CryptoKeyRSA::create(algorithm, hash, hasHash, CryptoKeyType::Public, ccPublicKey, true, usage); auto privateKey = CryptoKeyRSA::create(algorithm, hash, hasHash, CryptoKeyType::Private, ccPrivateKey, extractable, usage); (*localCallback)(CryptoKeyPair { WTFMove(publicKey), WTFMove(privateKey) }); delete localCallback; delete localFailureCallback; context.deref(); }); });