Title: [219449] trunk
Revision
219449
Author
zandober...@gmail.com
Date
2017-07-13 03:09:00 -0700 (Thu, 13 Jul 2017)

Log Message

[GCrypt] Implement CryptoKeyRSA SPKI exports
https://bugs.webkit.org/show_bug.cgi?id=173695

Reviewed by Jiewen Tan.

Source/WebCore:

Implement the SPKI export operation for RSA keys for platforms that use
libgcrypt.

In CryptoKeyRSA::exportSpki(), we bail early with an invalid access exception if
this export is not being done for a public key. Otherwise, we start with creating
the `RSAPublicKey` ASN.1 structure, filling in the modulus and public exponent
data that's retrieved from the `public-key` s-_expression_ in the signed MPI format.

We then create the `SubjectPublicKeyInfo` ASN.1 structure and fill it out with
the necessary data. The id-rsaEncryption object identifier is written out under
the `algorithm.algorithm` element, and a null value is written out under the
`algorithm.parameters` element. This doesn't follow the specification at the
moment, since id-RSASSA-PSS would have to be written for the RSA-PSS algorithm,
and id-RSAES-OAEP for the RSA-OAEP algorithm, along with specific parameter
structures. But no test in WebKit or the web-platform-tests suite covers this,
so this deviation should be addressed later.

Data of the previously-constructed `RSAPublicKey` structure is retrieved and
written out under the `subjectPublicKey` element, before finally retrieving
data of the `SubjectPublicKeyInfo` structure and returning that to the caller.

A helper mpiSignedData() function is added, providing overloads for gcry_mpi_t
and gcry_sexp_t parameters. MPI data for that parameter is retrieved and the
first byte of that data is tested, inserting an additional 0x00 byte at the
beginning of the Vector if that first byte has the first bit set, avoiding this
data accidentally being interpreted as a signed integer.

No new tests -- related tests are now passing and are unskipped.

* crypto/gcrypt/CryptoKeyRSAGCrypt.cpp:
(WebCore::CryptoKeyRSA::exportSpki):
* crypto/gcrypt/GCryptUtilities.h:
(WebCore::mpiSignedData):

LayoutTests:

* platform/gtk/TestExpectations: Unskip the RSA SPKI export tests
that are now passing.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (219448 => 219449)


--- trunk/LayoutTests/ChangeLog	2017-07-13 10:00:24 UTC (rev 219448)
+++ trunk/LayoutTests/ChangeLog	2017-07-13 10:09:00 UTC (rev 219449)
@@ -1,5 +1,15 @@
 2017-07-13  Zan Dobersek  <zdober...@igalia.com>
 
+        [GCrypt] Implement CryptoKeyRSA SPKI exports
+        https://bugs.webkit.org/show_bug.cgi?id=173695
+
+        Reviewed by Jiewen Tan.
+
+        * platform/gtk/TestExpectations: Unskip the RSA SPKI export tests
+        that are now passing.
+
+2017-07-13  Zan Dobersek  <zdober...@igalia.com>
+
         [GCrypt] Implement CryptoKeyRSA SPKI imports
         https://bugs.webkit.org/show_bug.cgi?id=173694
 

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (219448 => 219449)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2017-07-13 10:00:24 UTC (rev 219448)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2017-07-13 10:09:00 UTC (rev 219449)
@@ -762,7 +762,6 @@
 webkit.org/b/133122 crypto/subtle/ec-import-pkcs8-key-export-pkcs8-key-p384.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-export-key-malformed-parameters.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-import-jwk-key-export-pkcs8-key.html [ Skip ]
-webkit.org/b/133122 crypto/subtle/rsa-import-jwk-key-export-spki-key.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-import-pkcs8-key-export-jwk-key.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-import-pkcs8-key-export-pkcs8-key.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-import-spki-key-export-spki-key.html [ Skip ]
@@ -771,15 +770,11 @@
 webkit.org/b/133122 crypto/subtle/rsa-indexeddb-private.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-indexeddb.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-oaep-generate-export-key-pkcs8.html [ Skip ]
-webkit.org/b/133122 crypto/subtle/rsa-oaep-generate-export-key-spki.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-oaep-import-pkcs8-key.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsa-pss-generate-export-key-pkcs8.html [ Skip ]
-webkit.org/b/133122 crypto/subtle/rsa-pss-generate-export-key-spki.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-pkcs8.html [ Skip ]
-webkit.org/b/133122 crypto/subtle/rsaes-pkcs1-v1_5-generate-export-key-spki.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsaes-pkcs1-v1_5-import-pkcs8-key.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-pkcs8.html [ Skip ]
-webkit.org/b/133122 crypto/subtle/rsassa-pkcs1-v1_5-generate-export-key-spki.html [ Skip ]
 webkit.org/b/133122 crypto/subtle/rsassa-pkcs1-v1_5-import-pkcs8-key.html [ Skip ]
 webkit.org/b/133122 crypto/workers/subtle/aes-cfb-import-key-decrypt.html [ Skip ]
 webkit.org/b/133122 crypto/workers/subtle/aes-cfb-import-key-encrypt.html [ Skip ]
@@ -793,7 +788,6 @@
 webkit.org/b/133122 crypto/workers/subtle/multiple-postMessage-worker.html [ Skip ]
 webkit.org/b/133122 crypto/workers/subtle/raw-postMessage-worker.html [ Skip ]
 webkit.org/b/133122 crypto/workers/subtle/rsa-export-pkcs8-key.html [ Skip ]
-webkit.org/b/133122 crypto/workers/subtle/rsa-export-spki-key.html [ Skip ]
 webkit.org/b/133122 crypto/workers/subtle/rsa-import-pkcs8-key.html [ Skip ]
 webkit.org/b/133122 crypto/workers/subtle/rsa-postMessage-worker.html [ Skip ]
 webkit.org/b/133122 crypto/workers/subtle/rsa-pss-import-key-sign.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (219448 => 219449)


--- trunk/Source/WebCore/ChangeLog	2017-07-13 10:00:24 UTC (rev 219448)
+++ trunk/Source/WebCore/ChangeLog	2017-07-13 10:09:00 UTC (rev 219449)
@@ -1,5 +1,46 @@
 2017-07-13  Zan Dobersek  <zdober...@igalia.com>
 
+        [GCrypt] Implement CryptoKeyRSA SPKI exports
+        https://bugs.webkit.org/show_bug.cgi?id=173695
+
+        Reviewed by Jiewen Tan.
+
+        Implement the SPKI export operation for RSA keys for platforms that use
+        libgcrypt.
+
+        In CryptoKeyRSA::exportSpki(), we bail early with an invalid access exception if
+        this export is not being done for a public key. Otherwise, we start with creating
+        the `RSAPublicKey` ASN.1 structure, filling in the modulus and public exponent
+        data that's retrieved from the `public-key` s-_expression_ in the signed MPI format.
+
+        We then create the `SubjectPublicKeyInfo` ASN.1 structure and fill it out with
+        the necessary data. The id-rsaEncryption object identifier is written out under
+        the `algorithm.algorithm` element, and a null value is written out under the
+        `algorithm.parameters` element. This doesn't follow the specification at the
+        moment, since id-RSASSA-PSS would have to be written for the RSA-PSS algorithm,
+        and id-RSAES-OAEP for the RSA-OAEP algorithm, along with specific parameter
+        structures. But no test in WebKit or the web-platform-tests suite covers this,
+        so this deviation should be addressed later.
+
+        Data of the previously-constructed `RSAPublicKey` structure is retrieved and
+        written out under the `subjectPublicKey` element, before finally retrieving
+        data of the `SubjectPublicKeyInfo` structure and returning that to the caller.
+
+        A helper mpiSignedData() function is added, providing overloads for gcry_mpi_t
+        and gcry_sexp_t parameters. MPI data for that parameter is retrieved and the
+        first byte of that data is tested, inserting an additional 0x00 byte at the
+        beginning of the Vector if that first byte has the first bit set, avoiding this
+        data accidentally being interpreted as a signed integer.
+
+        No new tests -- related tests are now passing and are unskipped.
+
+        * crypto/gcrypt/CryptoKeyRSAGCrypt.cpp:
+        (WebCore::CryptoKeyRSA::exportSpki):
+        * crypto/gcrypt/GCryptUtilities.h:
+        (WebCore::mpiSignedData):
+
+2017-07-13  Zan Dobersek  <zdober...@igalia.com>
+
         [GCrypt] Implement CryptoKeyRSA SPKI imports
         https://bugs.webkit.org/show_bug.cgi?id=173694
 

Modified: trunk/Source/WebCore/crypto/gcrypt/CryptoKeyRSAGCrypt.cpp (219448 => 219449)


--- trunk/Source/WebCore/crypto/gcrypt/CryptoKeyRSAGCrypt.cpp	2017-07-13 10:00:24 UTC (rev 219448)
+++ trunk/Source/WebCore/crypto/gcrypt/CryptoKeyRSAGCrypt.cpp	2017-07-13 10:09:00 UTC (rev 219449)
@@ -330,9 +330,72 @@
 
 ExceptionOr<Vector<uint8_t>> CryptoKeyRSA::exportSpki() const
 {
-    notImplemented();
+    if (type() != CryptoKeyType::Public)
+        return Exception { INVALID_ACCESS_ERR };
 
-    return Exception { NOT_SUPPORTED_ERR };
+    PAL::TASN1::Structure rsaPublicKey;
+    {
+        // Create the `RSAPublicKey` structure.
+        if (!PAL::TASN1::createStructure("WebCrypto.RSAPublicKey", &rsaPublicKey))
+            return Exception { OperationError };
+
+        // Retrieve the modulus and public exponent s-expressions.
+        PAL::GCrypt::Handle<gcry_sexp_t> modulusSexp(gcry_sexp_find_token(m_platformKey, "n", 0));
+        PAL::GCrypt::Handle<gcry_sexp_t> publicExponentSexp(gcry_sexp_find_token(m_platformKey, "e", 0));
+        if (!modulusSexp || !publicExponentSexp)
+            return Exception { OperationError };
+
+        // Retrieve MPI data for the modulus and public exponent components.
+        auto modulus = mpiSignedData(modulusSexp);
+        auto publicExponent = mpiSignedData(publicExponentSexp);
+        if (!modulus || !publicExponent)
+            return Exception { OperationError };
+
+        // Write out the modulus data under `modulus`.
+        if (!PAL::TASN1::writeElement(rsaPublicKey, "modulus", modulus->data(), modulus->size()))
+            return Exception { OperationError };
+
+        // Write out the public exponent data under `publicExponent`.
+        if (!PAL::TASN1::writeElement(rsaPublicKey, "publicExponent", publicExponent->data(), publicExponent->size()))
+            return Exception { OperationError };
+    }
+
+    PAL::TASN1::Structure spki;
+    {
+        // Create the `SubjectPublicKeyInfo` structure.
+        if (!PAL::TASN1::createStructure("WebCrypto.SubjectPublicKeyInfo", &spki))
+            return Exception { OperationError };
+
+        // Write out the id-rsaEncryption identifier under `algorithm.algorithm`.
+        // FIXME: In case the key algorithm is:
+        // - RSA-PSS:
+        //     - this should write out id-RSASSA-PSS, along with setting `algorithm.parameters`
+        //       to a RSASSA-PSS-params structure
+        // - RSA-OAEP:
+        //     - this should write out id-RSAES-OAEP, along with setting `algorithm.parameters`
+        //       to a RSAES-OAEP-params structure
+        if (!PAL::TASN1::writeElement(spki, "algorithm.algorithm", "1.2.840.113549.1.1.1", 1))
+            return Exception { OperationError };
+
+        // Write out the null value under `algorithm.parameters`.
+        if (!PAL::TASN1::writeElement(spki, "algorithm.parameters", "\x05\x00", 2))
+            return Exception { OperationError };
+
+        // Write out the `RSAPublicKey` data under `subjectPublicKey`. Because this is a
+        // bit string parameter, the data size has to be multiplied by 8.
+        {
+            auto data = "" "");
+            if (!data || !PAL::TASN1::writeElement(spki, "subjectPublicKey", data->data(), data->size() * 8))
+                return Exception { OperationError };
+        }
+    }
+
+    // Retrieve the encoded `SubjectPublicKeyInfo` data and return it.
+    auto result = PAL::TASN1::encodedData(spki, "");
+    if (!result)
+        return Exception { OperationError };
+
+    return WTFMove(result.value());
 }
 
 ExceptionOr<Vector<uint8_t>> CryptoKeyRSA::exportPkcs8() const

Modified: trunk/Source/WebCore/crypto/gcrypt/GCryptUtilities.h (219448 => 219449)


--- trunk/Source/WebCore/crypto/gcrypt/GCryptUtilities.h	2017-07-13 10:00:24 UTC (rev 219448)
+++ trunk/Source/WebCore/crypto/gcrypt/GCryptUtilities.h	2017-07-13 10:09:00 UTC (rev 219449)
@@ -156,4 +156,28 @@
     return mpiData(paramMPI);
 }
 
+static inline std::optional<Vector<uint8_t>> mpiSignedData(gcry_mpi_t mpi)
+{
+    auto data = ""
+    if (!data)
+        return std::nullopt;
+
+    if (data->at(0) & 0x80)
+        data->insert(0, 0x00);
+
+    return data;
+}
+
+static inline std::optional<Vector<uint8_t>> mpiSignedData(gcry_sexp_t paramSexp)
+{
+    auto data = ""
+    if (!data)
+        return std::nullopt;
+
+    if (data->at(0) & 0x80)
+        data->insert(0, 0x00);
+
+    return data;
+}
+
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to