Changeset 159403 in webkit
- Timestamp:
- Nov 18, 2013, 12:42:41 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r159402 r159403 1 2013-11-17 Alexey Proskuryakov <ap@apple.com> 2 3 Support exporting public RSASSA-PKCS1-v1_5 keys 4 https://bugs.webkit.org/show_bug.cgi?id=124475 5 6 Reviewed by Sam Weinig. 7 8 * crypto/subtle/rsa-export-key-expected.txt: Added. 9 * crypto/subtle/rsa-export-key.html: Added. 10 1 11 2013-11-18 Zan Dobersek <zdobersek@igalia.com> 2 12 -
trunk/Source/WebCore/ChangeLog
r159393 r159403 1 2013-11-17 Alexey Proskuryakov <ap@apple.com> 2 3 Support exporting public RSASSA-PKCS1-v1_5 keys 4 https://bugs.webkit.org/show_bug.cgi?id=124475 5 6 Reviewed by Sam Weinig. 7 8 Test: crypto/subtle/rsa-export-key.html 9 10 * bindings/js/JSCryptoKeySerializationJWK.h: 11 * bindings/js/JSCryptoKeySerializationJWK.cpp: 12 (WebCore::JSCryptoKeySerializationJWK::buildJSONForRSAComponents): 13 (WebCore::JSCryptoKeySerializationJWK::addJWKAlgorithmToJSON): 14 (WebCore::JSCryptoKeySerializationJWK::serialize): 15 Added said support (this part works with private keys too). 16 17 * crypto/keys/CryptoKeyRSA.h: 18 * crypto/mac/CryptoKeyRSAMac.cpp: 19 (WebCore::CryptoKeyRSA::getPublicKeyComponents): Moved the logic for getting a 20 public key from private one here for reuse in keySizeInBits(). 21 (WebCore::CryptoKeyRSA::isRestrictedToHash): 22 (WebCore::CryptoKeyRSA::keySizeInBits): 23 (WebCore::CryptoKeyRSA::exportData): 24 Exposed information necessary for JWK serialization. 25 1 26 2013-11-17 Alexey Proskuryakov <ap@apple.com> 2 27 -
trunk/Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp
r159393 r159403 38 38 #include "CryptoKeyDataRSAComponents.h" 39 39 #include "CryptoKeyHMAC.h" 40 #include "CryptoKeyRSA.h" 40 41 #include "ExceptionCode.h" 41 42 #include "JSDOMBinding.h" … … 434 435 } 435 436 437 void JSCryptoKeySerializationJWK::buildJSONForRSAComponents(JSC::ExecState* exec, const CryptoKeyDataRSAComponents& data, JSC::JSObject* result) 438 { 439 addToJSON(exec, result, "kty", "RSA"); 440 addToJSON(exec, result, "n", base64URLEncode(data.modulus())); 441 addToJSON(exec, result, "e", base64URLEncode(data.exponent())); 442 443 if (data.type() == CryptoKeyDataRSAComponents::Type::Public) 444 return; 445 446 addToJSON(exec, result, "d", base64URLEncode(data.privateExponent())); 447 448 if (!data.hasAdditionalPrivateKeyParameters()) 449 return; 450 451 addToJSON(exec, result, "p", base64URLEncode(data.firstPrimeInfo().primeFactor)); 452 addToJSON(exec, result, "q", base64URLEncode(data.secondPrimeInfo().primeFactor)); 453 addToJSON(exec, result, "dp", base64URLEncode(data.firstPrimeInfo().factorCRTExponent)); 454 addToJSON(exec, result, "dq", base64URLEncode(data.secondPrimeInfo().factorCRTExponent)); 455 addToJSON(exec, result, "qi", base64URLEncode(data.secondPrimeInfo().factorCRTCoefficient)); 456 457 if (data.otherPrimeInfos().isEmpty()) 458 return; 459 460 JSArray* oth = constructEmptyArray(exec, 0, exec->lexicalGlobalObject(), data.otherPrimeInfos().size()); 461 for (size_t i = 0, size = data.otherPrimeInfos().size(); i < size; ++i) { 462 JSObject* jsPrimeInfo = constructEmptyObject(exec); 463 addToJSON(exec, jsPrimeInfo, "r", base64URLEncode(data.otherPrimeInfos()[i].primeFactor)); 464 addToJSON(exec, jsPrimeInfo, "d", base64URLEncode(data.otherPrimeInfos()[i].factorCRTExponent)); 465 addToJSON(exec, jsPrimeInfo, "t", base64URLEncode(data.otherPrimeInfos()[i].factorCRTCoefficient)); 466 oth->putDirectIndex(exec, i, jsPrimeInfo); 467 } 468 result->putDirect(exec->vm(), Identifier(exec, "oth"), oth); 469 } 470 436 471 void JSCryptoKeySerializationJWK::addToJSON(ExecState* exec, JSObject* json, const char* key, const String& value) 437 472 { … … 483 518 } 484 519 break; 520 case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5: { 521 const CryptoKeyRSA& rsaKey = toCryptoKeyRSA(key); 522 CryptoAlgorithmIdentifier hash; 523 if (!rsaKey.isRestrictedToHash(hash)) 524 break; 525 if (rsaKey.keySizeInBits() < 2048) 526 break; 527 switch (hash) { 528 case CryptoAlgorithmIdentifier::SHA_256: 529 jwkAlgorithm = "RS256"; 530 break; 531 case CryptoAlgorithmIdentifier::SHA_384: 532 jwkAlgorithm = "RS384"; 533 break; 534 case CryptoAlgorithmIdentifier::SHA_512: 535 jwkAlgorithm = "RS512"; 536 break; 537 default: 538 break; 539 } 540 break; 541 } 485 542 default: 486 543 break; … … 535 592 if (isCryptoKeyDataOctetSequence(*keyData)) 536 593 buildJSONForOctetSequence(exec, toCryptoKeyDataOctetSequence(*keyData).octetSequence(), result); 594 else if (isCryptoKeyDataRSAComponents(*keyData)) 595 buildJSONForRSAComponents(exec, toCryptoKeyDataRSAComponents(*keyData), result); 537 596 else { 538 597 throwTypeError(exec, "Key doesn't support exportKey"); 539 598 return String(); 540 599 } 541 ASSERT(!exec->hadException()); 600 if (exec->hadException()) 601 return String(); 542 602 543 603 return JSONStringify(exec, result, 4); -
trunk/Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.h
r159390 r159403 43 43 class CryptoAlgorithmParameters; 44 44 class CryptoKey; 45 class CryptoKeyDataRSAComponents; 45 46 46 47 class JSCryptoKeySerializationJWK FINAL : public CryptoKeySerialization { … … 67 68 68 69 static void buildJSONForOctetSequence(JSC::ExecState*, const Vector<uint8_t>&, JSC::JSObject* result); 70 static void buildJSONForRSAComponents(JSC::ExecState*, const CryptoKeyDataRSAComponents&, JSC::JSObject* result); 69 71 static void addJWKAlgorithmToJSON(JSC::ExecState*, JSC::JSObject*, const CryptoKey& key); 70 72 static void addJWKUseToJSON(JSC::ExecState*, JSC::JSObject*, CryptoKeyUsage); -
trunk/Source/WebCore/crypto/keys/CryptoKeyRSA.h
r159390 r159403 52 52 53 53 void restrictToHash(CryptoAlgorithmIdentifier); 54 bool isRestrictedToHash(CryptoAlgorithmIdentifier&) const; 55 56 size_t keySizeInBits() const; 54 57 55 58 static void generatePair(CryptoAlgorithmIdentifier, unsigned modulusLength, const Vector<uint8_t>& publicExponent, bool extractable, CryptoKeyUsage, std::unique_ptr<PromiseWrapper>); 56 57 virtual CryptoKeyClass keyClass() const OVERRIDE { return CryptoKeyClass::RSA; }58 59 59 60 PlatformRSAKey platformKey() const { return m_platformKey; } … … 61 62 private: 62 63 CryptoKeyRSA(CryptoAlgorithmIdentifier, CryptoKeyType, PlatformRSAKey, bool extractable, CryptoKeyUsage); 64 65 virtual CryptoKeyClass keyClass() const OVERRIDE { return CryptoKeyClass::RSA; } 63 66 64 67 virtual void buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder&) const OVERRIDE; -
trunk/Source/WebCore/crypto/mac/CryptoKeyRSAMac.cpp
r159390 r159403 61 61 static CCCryptorStatus getPublicKeyComponents(CCRSACryptorRef rsaKey, Vector<uint8_t>& modulus, Vector<uint8_t>& publicExponent) 62 62 { 63 ASSERT(CCRSAGetKeyType(rsaKey) == ccRSAKeyPublic); 63 ASSERT(CCRSAGetKeyType(rsaKey) == ccRSAKeyPublic || CCRSAGetKeyType(rsaKey) == ccRSAKeyPrivate); 64 bool keyIsPublic = CCRSAGetKeyType(rsaKey) == ccRSAKeyPublic; 65 CCRSACryptorRef publicKey = keyIsPublic ? rsaKey : CCRSACryptorGetPublicKeyFromPrivateKey(rsaKey); 64 66 65 67 modulus.resize(16384); … … 67 69 publicExponent.resize(16384); 68 70 size_t exponentLength = publicExponent.size(); 69 CCCryptorStatus status = CCRSAGetKeyComponents(rsaKey, modulus.data(), &modulusLength, publicExponent.data(), &exponentLength, 0, 0, 0, 0); 71 CCCryptorStatus status = CCRSAGetKeyComponents(publicKey, modulus.data(), &modulusLength, publicExponent.data(), &exponentLength, 0, 0, 0, 0); 72 if (!keyIsPublic) { 73 // CCRSACryptorGetPublicKeyFromPrivateKey has "Get" in the name, but its result needs to be released (see <rdar://problem/15449697>). 74 CCRSACryptorRelease(publicKey); 75 } 70 76 if (status) 71 77 return status; … … 123 129 } 124 130 125 void CryptoKeyRSA::buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder& builder) const 126 { 127 CryptoKey::buildAlgorithmDescription(builder); 128 129 ASSERT(CCRSAGetKeyType(m_platformKey) == ccRSAKeyPublic || CCRSAGetKeyType(m_platformKey) == ccRSAKeyPrivate); 130 bool platformKeyIsPublic = CCRSAGetKeyType(m_platformKey) == ccRSAKeyPublic; 131 CCRSACryptorRef publicKey = platformKeyIsPublic ? m_platformKey : CCRSACryptorGetPublicKeyFromPrivateKey(m_platformKey); 132 131 bool CryptoKeyRSA::isRestrictedToHash(CryptoAlgorithmIdentifier& identifier) const 132 { 133 if (!m_restrictedToSpecificHash) 134 return false; 135 136 identifier = m_hash; 137 return true; 138 } 139 140 size_t CryptoKeyRSA::keySizeInBits() const 141 { 133 142 Vector<uint8_t> modulus; 134 143 Vector<uint8_t> publicExponent; 135 CCCryptorStatus status = getPublicKeyComponents(publicKey, modulus, publicExponent); 136 if (!platformKeyIsPublic) { 137 // CCRSACryptorGetPublicKeyFromPrivateKey has "Get" in the name, but its result needs to be released (see <rdar://problem/15449697>). 138 CCRSACryptorRelease(publicKey); 139 } 144 CCCryptorStatus status = getPublicKeyComponents(m_platformKey, modulus, publicExponent); 145 if (status) { 146 WTFLogAlways("Couldn't get RSA key components, status %d", status); 147 return 0; 148 } 149 150 return modulus.size() * 8; 151 } 152 153 void CryptoKeyRSA::buildAlgorithmDescription(CryptoAlgorithmDescriptionBuilder& builder) const 154 { 155 CryptoKey::buildAlgorithmDescription(builder); 156 157 Vector<uint8_t> modulus; 158 Vector<uint8_t> publicExponent; 159 CCCryptorStatus status = getPublicKeyComponents(m_platformKey, modulus, publicExponent); 140 160 if (status) { 141 161 WTFLogAlways("Couldn't get RSA key components, status %d", status); … … 155 175 std::unique_ptr<CryptoKeyData> CryptoKeyRSA::exportData() const 156 176 { 157 // Not implemented yet.158 177 ASSERT(extractable()); 159 return nullptr; 178 179 switch (CCRSAGetKeyType(m_platformKey)) { 180 case ccRSAKeyPublic: { 181 Vector<uint8_t> modulus; 182 Vector<uint8_t> publicExponent; 183 CCCryptorStatus status = getPublicKeyComponents(m_platformKey, modulus, publicExponent); 184 if (status) { 185 WTFLogAlways("Couldn't get RSA key components, status %d", status); 186 return nullptr; 187 } 188 return CryptoKeyDataRSAComponents::createPublic(modulus, publicExponent); 189 } 190 case ccRSAKeyPrivate: 191 // Not supported yet. 192 default: 193 return nullptr; 194 } 160 195 } 161 196
Note:
See TracChangeset
for help on using the changeset viewer.