Changeset 218626 in webkit
- Timestamp:
- Jun 20, 2017, 11:52:29 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r218553 r218626 1 2017-06-20 Zan Dobersek <zdobersek@igalia.com> 2 3 [GCrypt] Implement CryptoKeyEC SPKI imports 4 https://bugs.webkit.org/show_bug.cgi?id=172927 5 6 Reviewed by Jiewen Tan, Michael Catanzaro and Carlos Garcia Campos. 7 8 * Source/cmake/FindLibtasn1.cmake: Added. 9 * Source/cmake/OptionsGTK.cmake: Require libtasn1 when SUBTLE_CRYPTO is enabled. 10 * Source/cmake/OptionsWPE.cmake: Ditto. 11 1 12 2017-06-20 Carlos Garcia Campos <cgarcia@igalia.com> 2 13 -
trunk/LayoutTests/ChangeLog
r218620 r218626 1 2017-06-20 Zan Dobersek <zdobersek@igalia.com> 2 3 [GCrypt] Implement CryptoKeyEC SPKI imports 4 https://bugs.webkit.org/show_bug.cgi?id=172927 5 6 Reviewed by Jiewen Tan, Michael Catanzaro and Carlos Garcia Campos. 7 8 * platform/gtk/TestExpectations: 9 Unskip or enable the EC-based SPKI import tests that are now passing. 10 1 11 2017-06-20 Myles C. Maxfield <mmaxfield@apple.com> 2 12 -
trunk/LayoutTests/platform/gtk/TestExpectations
r218558 r218626 759 759 webkit.org/b/133122 crypto/subtle/ecdh-import-pkcs8-key-p256.html [ Skip ] 760 760 webkit.org/b/133122 crypto/subtle/ecdh-import-pkcs8-key-p384.html [ Skip ] 761 webkit.org/b/133122 crypto/subtle/ecdh-import-spki-key-p256.html [ Skip ]762 webkit.org/b/133122 crypto/subtle/ecdh-import-spki-key-p384.html [ Skip ]763 761 webkit.org/b/133122 crypto/subtle/ecdsa-generate-export-key-pkcs8.html [ Skip ] 764 762 webkit.org/b/133122 crypto/subtle/ecdsa-generate-export-key-spki.html [ Skip ] 765 763 webkit.org/b/133122 crypto/subtle/ecdsa-import-pkcs8-key.html [ Skip ] 766 webkit.org/b/133122 crypto/subtle/ecdsa-import-spki-key.html [ Skip ]767 764 webkit.org/b/133122 crypto/subtle/ec-import-jwk-key-export-pkcs8-key.html [ Skip ] 768 765 webkit.org/b/133122 crypto/subtle/ec-import-jwk-key-export-spki-key.html [ Skip ] … … 771 768 webkit.org/b/133122 crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p256.html [ Skip ] 772 769 webkit.org/b/133122 crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html [ Skip ] 773 webkit.org/b/133122 crypto/subtle/ec-import-spki-key-export-jwk-key.html [ Skip ]774 webkit.org/b/133122 crypto/subtle/ec-import-spki-key-export-raw-key.html [ Skip ]775 770 webkit.org/b/133122 crypto/subtle/ec-import-spki-key-export-spki-key-p256.html [ Skip ] 776 771 webkit.org/b/133122 crypto/subtle/ec-import-spki-key-export-spki-key-p384.html [ Skip ] … … 812 807 webkit.org/b/133122 crypto/workers/subtle/ec-generate-export-spki-key.html [ Skip ] 813 808 webkit.org/b/133122 crypto/workers/subtle/ec-import-pkcs8-key.html [ Skip ] 814 webkit.org/b/133122 crypto/workers/subtle/ec-import-spki-key.html [ Skip ]815 809 webkit.org/b/133122 crypto/workers/subtle/ec-postMessage-worker.html [ Skip ] 816 810 webkit.org/b/133122 crypto/workers/subtle/hmac-postMessage-worker.html [ Skip ] … … 844 838 crypto/workers/subtle/rsa-pss-import-key-sign.html [ Pass ] 845 839 crypto/workers/subtle/rsa-pss-import-key-verify.html [ Pass ] 840 841 # libgcrypt-based implementation supports ecDH algorithm identifier for ECDH SPKI imports. 842 crypto/subtle/ecdh-import-spki-key-ecdh-identifier.html [ Pass ] 846 843 847 844 # These are legacy APIs that we don't support, apart from a few digest algorithms. -
trunk/Source/WebCore/ChangeLog
r218624 r218626 1 2017-06-20 Zan Dobersek <zdobersek@igalia.com> 2 3 [GCrypt] Implement CryptoKeyEC SPKI imports 4 https://bugs.webkit.org/show_bug.cgi?id=172927 5 6 Reviewed by Jiewen Tan, Michael Catanzaro and Carlos Garcia Campos. 7 8 No new tests -- affected tests are now passing and are unskipped. 9 10 Implement libgcrypt-based support for SPKI imports of EC keys. 11 12 Using libtasn1 through the utility functions and wrappers, the given key data 13 is decoded against the SubjectPublicKeyInfo ASN.1 definition. The algorithm 14 member is then properly validated, making sure that the key algorithm idenfitier 15 is supported and that the algorithm parameters specify the correct EC curve. 16 17 The public key bit string is then retrieved and validated, ensuring it represents 18 an uncompressed EC point that is of valid size for the specified EC curve. The 19 point is then tested through an EC context to make sure it's positioned on the 20 specified EC curve. 21 22 Finally, the curve name and uncompressed point data are embedded into a 23 `public-key` s-expression that will be used through the libgcrypt API. This is 24 then used, along with other information, to create a valid CryptoKeyEC object. 25 26 * PlatformGTK.cmake: Use LIBTASN1_INCLUDE_DIRECTORIES and LIBTASN1_LIBRARIES. 27 * PlatformWPE.cmake: Ditto. 28 * crypto/gcrypt/CryptoKeyECGCrypt.cpp: 29 (WebCore::supportedAlgorithmIdentifier): 30 (WebCore::curveForIdentifier): 31 (WebCore::CryptoKeyEC::platformImportSpki): 32 1 33 2017-06-20 Devin Rousso <drousso@apple.com> 2 34 -
trunk/Source/WebCore/PAL/ChangeLog
r218620 r218626 1 2017-06-20 Zan Dobersek <zdobersek@igalia.com> 2 3 [GCrypt] Implement CryptoKeyEC SPKI imports 4 https://bugs.webkit.org/show_bug.cgi?id=172927 5 6 Reviewed by Jiewen Tan, Michael Catanzaro and Carlos Garcia Campos. 7 8 Add a file that provides utility functions for operating with libtasn1 APIs. 9 10 The precomputed ASN.1 declarations, generated from the WebCrypto.asn file with 11 the asn1Parser tool, are used to enable construction of ASN.1 structures that 12 are then used to decode the SPKI or PKCS#8 data through the decodeStructure() 13 function. Raw data of each element in that structure can be retrieved throug the 14 elementData() function. 15 16 The Structure class is added as a wrapper for asn1_node objects that are used 17 as decoding targets, simplifying lifetime management of these objects. 18 19 * pal/PlatformGTK.cmake: 20 * pal/PlatformWPE.cmake: 21 * pal/crypto/tasn1/Utilities.cpp: Added. 22 (PAL::TASN1::asn1Definitions): 23 (PAL::TASN1::decodeStructure): 24 (PAL::TASN1::elementData): 25 * pal/crypto/tasn1/Utilities.h: Added. 26 (PAL::TASN1::Structure::~Structure): 27 (PAL::TASN1::Structure::operator&): 28 (PAL::TASN1::Structure::operator asn1_node): 29 * pal/crypto/tasn1/WebCrypto.asn: Added. 30 1 31 2017-06-20 Myles C. Maxfield <mmaxfield@apple.com> 2 32 -
trunk/Source/WebCore/PAL/pal/PlatformGTK.cmake
r211027 r218626 1 1 list(APPEND PAL_SOURCES 2 2 crypto/gcrypt/CryptoDigestGCrypt.cpp 3 4 crypto/tasn1/Utilities.cpp 3 5 ) -
trunk/Source/WebCore/PAL/pal/PlatformWPE.cmake
r216497 r218626 1 1 list(APPEND PAL_SOURCES 2 2 crypto/gcrypt/CryptoDigestGCrypt.cpp 3 4 crypto/tasn1/Utilities.cpp 3 5 ) -
trunk/Source/WebCore/PlatformGTK.cmake
r217971 r218626 220 220 ${LIBSECRET_LIBRARIES} 221 221 ${LIBSOUP_LIBRARIES} 222 ${LIBTASN1_LIBRARIES} 222 223 ${LIBXML2_LIBRARIES} 223 224 ${LIBXSLT_LIBRARIES} … … 246 247 ${LIBSECRET_INCLUDE_DIRS} 247 248 ${LIBSOUP_INCLUDE_DIRS} 249 ${LIBTASN1_INCLUDE_DIRS} 248 250 ${LIBXML2_INCLUDE_DIR} 249 251 ${LIBXSLT_INCLUDE_DIR} -
trunk/Source/WebCore/PlatformWPE.cmake
r217925 r218626 172 172 ${LIBGCRYPT_LIBRARIES} 173 173 ${LIBSOUP_LIBRARIES} 174 ${LIBTASN1_LIBRARIES} 174 175 ${LIBXML2_LIBRARIES} 175 176 ${LIBXSLT_LIBRARIES} … … 186 187 ${LIBGCRYPT_INCLUDE_DIRS} 187 188 ${LIBSOUP_INCLUDE_DIRS} 189 ${LIBTASN1_INCLUDE_DIRS} 188 190 ${LIBXML2_INCLUDE_DIR} 189 191 ${LIBXSLT_INCLUDE_DIR} -
trunk/Source/WebCore/crypto/gcrypt/CryptoKeyECGCrypt.cpp
r218100 r218626 35 35 #include <pal/crypto/gcrypt/Handle.h> 36 36 #include <pal/crypto/gcrypt/Utilities.h> 37 #include <pal/crypto/tasn1/Utilities.h> 37 38 #include <wtf/text/Base64.h> 38 39 … … 194 195 } 195 196 196 RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&&, bool, CryptoKeyUsageBitmap) 197 { 198 notImplemented(); 199 200 return nullptr; 197 static bool supportedAlgorithmIdentifier(CryptoAlgorithmIdentifier keyIdentifier, const Vector<uint8_t>& identifier) 198 { 199 static const std::array<uint8_t, 18> s_id_ecPublicKey { { "1.2.840.10045.2.1" } }; 200 static const std::array<uint8_t, 13> s_id_ecDH { { "1.3.132.1.12" } }; 201 202 auto size = identifier.size(); 203 auto* data = identifier.data(); 204 205 switch (keyIdentifier) { 206 case CryptoAlgorithmIdentifier::ECDSA: 207 // ECDSA only supports id-ecPublicKey algorithms for imported keys. 208 if (size == s_id_ecPublicKey.size() && !std::memcmp(data, s_id_ecPublicKey.data(), size)) 209 return true; 210 return false; 211 case CryptoAlgorithmIdentifier::ECDH: 212 // ECDH supports both id-ecPublicKey and ic-ecDH algorithms for imported keys. 213 if (size == s_id_ecPublicKey.size() && !std::memcmp(data, s_id_ecPublicKey.data(), size)) 214 return true; 215 if (size == s_id_ecDH.size() && !std::memcmp(data, s_id_ecDH.data(), size)) 216 return true; 217 return false; 218 default: 219 ASSERT_NOT_REACHED(); 220 break; 221 } 222 223 return false; 224 } 225 226 static std::optional<CryptoKeyEC::NamedCurve> curveForIdentifier(const Vector<uint8_t>& identifier) 227 { 228 static const std::array<uint8_t, 20> s_secp256r1 { { "1.2.840.10045.3.1.7" } }; 229 static const std::array<uint8_t, 13> s_secp384r1 { { "1.3.132.0.34" } }; 230 static const std::array<uint8_t, 13> s_secp521r1 { { "1.3.132.0.35" } }; 231 232 auto size = identifier.size(); 233 auto* data = identifier.data(); 234 235 if (size == s_secp256r1.size() && !std::memcmp(data, s_secp256r1.data(), size)) 236 return CryptoKeyEC::NamedCurve::P256; 237 if (size == s_secp384r1.size() && !std::memcmp(data, s_secp384r1.data(), size)) 238 return CryptoKeyEC::NamedCurve::P384; 239 if (size == s_secp521r1.size() && !std::memcmp(data, s_secp521r1.data(), size)) 240 return std::nullopt; // Not yet supported. 241 242 return std::nullopt; 243 } 244 245 RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages) 246 { 247 // Decode the `SubjectPublicKeyInfo` structure using the provided key data. 248 PAL::TASN1::Structure spki; 249 if (!PAL::TASN1::decodeStructure(&spki, "WebCrypto.SubjectPublicKeyInfo", keyData)) 250 return nullptr; 251 252 // Validate `algorithm.algorithm`. 253 { 254 auto algorithm = PAL::TASN1::elementData(spki, "algorithm.algorithm"); 255 if (!algorithm) 256 return nullptr; 257 258 if (!supportedAlgorithmIdentifier(identifier, *algorithm)) 259 return nullptr; 260 } 261 262 // Validate `algorithm.parameters` and therein embedded `ECParameters`. 263 { 264 auto parameters = PAL::TASN1::elementData(spki, "algorithm.parameters"); 265 if (!parameters) 266 return nullptr; 267 268 // Decode the `ECParameters` structure using the `algorithm.parameters` data. 269 PAL::TASN1::Structure ecParameters; 270 if (!PAL::TASN1::decodeStructure(&ecParameters, "WebCrypto.ECParameters", *parameters)) 271 return nullptr; 272 273 auto namedCurve = PAL::TASN1::elementData(ecParameters, "namedCurve"); 274 if (!namedCurve) 275 return nullptr; 276 277 auto parameterCurve = curveForIdentifier(*namedCurve); 278 if (!parameterCurve || *parameterCurve != curve) 279 return nullptr; 280 } 281 282 // Retrieve the `subjectPublicKey` data and embed it into the `public-key` s-expression. 283 PAL::GCrypt::Handle<gcry_sexp_t> platformKey; 284 { 285 auto subjectPublicKey = PAL::TASN1::elementData(spki, "subjectPublicKey"); 286 if (!subjectPublicKey) 287 return nullptr; 288 289 // Bail if the `subjectPublicKey` data size doesn't match the size of an uncompressed point 290 // for this curve, or if the first byte in the `subjectPublicKey` data isn't 0x04, as required 291 // for an uncompressed EC point encoded in an octet string. 292 if (subjectPublicKey->size() != uncompressedPointSizeForCurve(curve) || subjectPublicKey->at(0) != 0x04) 293 return nullptr; 294 295 // Convert X and Y coordinate data into MPIs. 296 unsigned coordinateSize = uncompressedFieldElementSizeForCurve(curve); 297 PAL::GCrypt::Handle<gcry_mpi_t> xMPI, yMPI; 298 { 299 gcry_error_t error = gcry_mpi_scan(&xMPI, GCRYMPI_FMT_USG, &subjectPublicKey->at(1), coordinateSize, nullptr); 300 if (error != GPG_ERR_NO_ERROR) { 301 PAL::GCrypt::logError(error); 302 return nullptr; 303 } 304 305 error = gcry_mpi_scan(&yMPI, GCRYMPI_FMT_USG, &subjectPublicKey->at(1 + coordinateSize), coordinateSize, nullptr); 306 if (error != GPG_ERR_NO_ERROR) { 307 PAL::GCrypt::logError(error); 308 return nullptr; 309 } 310 } 311 312 // Construct an MPI point from the X and Y coordinates and using 1 as the Z coordinate. 313 // This always allocates the gcry_mpi_point_t object. 314 PAL::GCrypt::Handle<gcry_mpi_point_t> point(gcry_mpi_point_set(nullptr, xMPI, yMPI, GCRYMPI_CONST_ONE)); 315 316 // Create an EC context for the specified curve. 317 PAL::GCrypt::Handle<gcry_ctx_t> context; 318 gcry_error_t error = gcry_mpi_ec_new(&context, nullptr, curveName(curve)); 319 if (error != GPG_ERR_NO_ERROR) { 320 PAL::GCrypt::logError(error); 321 return nullptr; 322 } 323 324 // Bail if the constructed MPI point is not on the specified EC curve. 325 if (!gcry_mpi_ec_curve_point(point, context)) 326 return nullptr; 327 328 error = gcry_sexp_build(&platformKey, nullptr, "(public-key(ecc(curve %s)(q %b)))", 329 curveName(curve), subjectPublicKey->size(), subjectPublicKey->data()); 330 if (error != GPG_ERR_NO_ERROR) { 331 PAL::GCrypt::logError(error); 332 return nullptr; 333 } 334 } 335 336 // Finally create a new CryptoKeyEC object, transferring to it ownership of the `public-key` s-expression. 337 return create(identifier, curve, CryptoKeyType::Public, platformKey.release(), extractable, usages); 201 338 } 202 339 -
trunk/Source/cmake/OptionsGTK.cmake
r218478 r218626 272 272 273 273 if (ENABLE_SUBTLE_CRYPTO) 274 find_package(Libtasn1 REQUIRED) 275 if (NOT LIBTASN1_FOUND) 276 message(FATAL_ERROR "libtasn1 is required to enable Web Crypto API support.") 277 endif () 274 278 if (LIBGCRYPT_VERSION VERSION_LESS 1.7.0) 275 279 message(FATAL_ERROR "libgcrypt 1.7.0 is required to enable Web Crypto API support.") -
trunk/Source/cmake/OptionsWPE.cmake
r218553 r218626 120 120 121 121 if (ENABLE_SUBTLE_CRYPTO) 122 find_package(Libtasn1 REQUIRED) 123 if (NOT LIBTASN1_FOUND) 124 message(FATAL_ERROR "libtasn1 is required to enable Web Crypto API support.") 125 endif () 122 126 if (LIBGCRYPT_VERSION VERSION_LESS 1.7.0) 123 127 message(FATAL_ERROR "libgcrypt 1.7.0 is required to enable Web Crypto API support.")
Note:
See TracChangeset
for help on using the changeset viewer.