Skip to content

Commit 54b9ee3

Browse files
panvatwiss
authored andcommitted
Add getPublicKey method (#17)
1 parent 11e06ab commit 54b9ee3

File tree

2 files changed

+169
-3
lines changed

2 files changed

+169
-3
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Additionally, it proposes to add functions for key encapsulation and decapsulati
1717
`SubtleCrypto.decapsulateKey` and `SubtleCrypto.decapsulateBits`.
1818

1919
Finally, it proposes to add a `SubtleCrypto.supports` function,
20-
for improved algorithm support detection.
20+
for improved algorithm support detection and a `SubtleCrypto.getPublicKey`
21+
to be able to derive a public key from its corresponding private key.
2122

2223
See the [draft specification](https://twiss.github.io/webcrypto-modern-algos/).

index.html

Lines changed: 167 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ <h2>Introduction</h2>
134134
<a href="#dfn-SubtleCrypto-method-decapsulateKey">`SubtleCrypto.decapsulateKey`</a> and
135135
<a href="#dfn-SubtleCrypto-method-decapsulateBits">`SubtleCrypto.decapsulateBits`</a>.
136136
</p>
137+
<p>
138+
Additionally, this proposal also introduces the <a href="#dfn-SubtleCrypto-method-getPublicKey">`SubtleCrypto.getPublicKey`</a> function,
139+
which provides a convenient way to derive a public key from an asymmetric private key,
140+
eliminating the need to store both the public and private key separately when only the private key is needed.
141+
</p>
137142
<p>
138143
Finally, this proposal aims to make feature detection easier,
139144
by adding a <a href="#dfn-SubtleCrypto-method-supports">`SubtleCrypto.supports`</a> function,
@@ -187,6 +192,11 @@ <h2>Partial SubtleCrypto interface</h2>
187192
BufferSource ciphertext
188193
);
189194

195+
Promise&lt;CryptoKey> getPublicKey(
196+
CryptoKey key,
197+
sequence&lt;KeyUsage> keyUsages
198+
);
199+
190200
static boolean supports(DOMString operation,
191201
AlgorithmIdentifier algorithm,
192202
optional unsigned long? length = null);
@@ -720,6 +730,128 @@ <h4>The decapsulateBits method</h4>
720730
</li>
721731
</ol>
722732
</section>
733+
734+
<section id="SubtleCrypto-method-getPublicKey">
735+
<h4>The getPublicKey method</h4>
736+
<p>
737+
The <dfn id="dfn-SubtleCrypto-method-getPublicKey" data-dfn-for=SubtleCrypto data-lt="getPublicKey">getPublicKey(|key|, |usages|)</dfn>
738+
method returns the public key corresponding to a given private key.
739+
It behaves as follows:
740+
</p>
741+
<ol>
742+
<li>
743+
<p>
744+
Let |key| and |usages| be the `key` and `keyUsages` parameters passed to the
745+
{{SubtleCrypto/getPublicKey()}} method,
746+
respectively.
747+
</p>
748+
</li>
749+
<li>
750+
<p>
751+
Let |algorithm| be the <a data-cite="webcrypto#dfn-CryptoKey-slot-algorithm">`[[algorithm]]`</a> internal slot of |key|.
752+
</p>
753+
</li>
754+
<li>
755+
<p>
756+
If the cryptographic algorithm identified by |algorithm|
757+
does not support deriving a public key from a private key,
758+
then return a Promise rejected with a {{NotSupportedError}}.
759+
</p>
760+
</li>
761+
<li>
762+
<p>
763+
Let |realm| be the [= relevant realm =] of [= this =].
764+
</p>
765+
</li>
766+
<li>
767+
<p>
768+
Let |promise| be a new Promise.
769+
</p>
770+
</li>
771+
<li>
772+
<p>
773+
Return |promise| and perform the remaining steps [= in parallel =].
774+
</p>
775+
</li>
776+
<li>
777+
<p>
778+
If the following steps or referenced procedures say to
779+
[= exception/throw =] an error,
780+
[= queue a global task =] on the <a data-cite="webcrypto#dfn-crypto-task-source">crypto task source</a>,
781+
given |realm|'s global object,
782+
to reject |promise| with the returned error;
783+
and then <a data-cite="webcrypto#terminate-the-algorithm">terminate the algorithm</a>.
784+
</p>
785+
</li>
786+
<li>
787+
<p>
788+
If the <a data-cite="webcrypto#dfn-CryptoKey-slot-type">`[[type]]`</a> internal slot of
789+
|key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}.
790+
</p>
791+
</li>
792+
<li>
793+
<p>
794+
If |usages| contains an entry which is not supported for a public key
795+
by the algorithm identified by |algorithm|,
796+
then [= exception/throw =] a {{SyntaxError}}.
797+
</p>
798+
</li>
799+
<li>
800+
<p>
801+
Let |publicKey| be a new {{CryptoKey}} representing the public key corresponding to
802+
the private key represented by the <a data-cite="webcrypto#dfn-CryptoKey-slot-handle">`[[handle]]`</a>
803+
internal slot of |key|.
804+
</p>
805+
</li>
806+
<li>
807+
<p>
808+
If an error occurred, then [= exception/throw =] a {{OperationError}}.
809+
</p>
810+
</li>
811+
<li>
812+
<p>
813+
Set the <a data-cite="webcrypto#dfn-CryptoKey-slot-type">`[[type]]`</a> internal slot of
814+
|publicKey| to {{KeyType/"public"}}.
815+
</p>
816+
</li>
817+
<li>
818+
<p>
819+
Set the <a data-cite="webcrypto#dfn-CryptoKey-slot-algorithm">`[[algorithm]]`</a> internal
820+
slot of |publicKey| to |publicKeyAlgorithm|.
821+
</p>
822+
</li>
823+
<li>
824+
<p>
825+
Set the <a data-cite="webcrypto#dfn-CryptoKey-slot-extractable">`[[extractable]]`</a> internal
826+
slot of |publicKey| to true.
827+
</p>
828+
</li>
829+
<li>
830+
<p>
831+
Set the <a data-cite="webcrypto#dfn-CryptoKey-slot-usages">`[[usages]]`</a> internal slot of
832+
|publicKey| to |usages|.
833+
</p>
834+
</li>
835+
<li>
836+
<p>
837+
[= Queue a global task =] on the <a data-cite="webcrypto#dfn-crypto-task-source">crypto task source</a>,
838+
given |realm|'s global object, to perform the remaining steps.
839+
</p>
840+
</li>
841+
<li>
842+
<p>
843+
Let |result| be the result of converting |publicKey| to an ECMAScript Object in |realm|, as defined by [[WebIDL]].
844+
</p>
845+
</li>
846+
<li>
847+
<p>
848+
Resolve |promise| with
849+
|result|.
850+
</p>
851+
</li>
852+
</ol>
853+
</section>
854+
723855
<section id="SubtleCrypto-method-supports">
724856
<h4>The supports method</h4>
725857
<p>
@@ -737,7 +869,7 @@ <h4>The supports method</h4>
737869
"`digest`", "`generateKey`", "`deriveKey`", "`deriveBits`",
738870
"`importKey`", "`exportKey`", "`wrapKey`", "`unwrapKey`",
739871
"`encapsulateKey`", "`encapsulateBits`",
740-
"`decapsulateKey`" or "`decapsulateBits`",
872+
"`decapsulateKey`", "`decapsulateBits`" or "`getPublicKey`",
741873
return false.
742874
</p>
743875
</li>
@@ -766,7 +898,7 @@ <h4>The supports method</h4>
766898
"`digest`", "`generateKey`", "`deriveKey`", "`deriveBits`",
767899
"`importKey`", "`exportKey`", "`wrapKey`", "`unwrapKey`",
768900
"`encapsulateKey`", "`encapsulateBits`",
769-
"`decapsulateKey`" or "`decapsulateBits`",
901+
"`decapsulateKey`", "`decapsulateBits`" or "`getPublicKey`",
770902
return false.
771903
</p>
772904
</li>
@@ -868,6 +1000,39 @@ <h3>Checking support for an algorithm</h3>
8681000
If |op| is "`decapsulateKey`" or "`decapsulateBits`", set |op| to "`decapsulate`".
8691001
</p>
8701002
</li>
1003+
<li>
1004+
<dl class="switch">
1005+
<dt>If |op| is "`getPublicKey`":</dt>
1006+
<dd>
1007+
<ol>
1008+
<li>
1009+
<p>
1010+
Let |normalizedAlgorithm| be the result of
1011+
<a data-cite="webcrypto#dfn-normalize-an-algorithm">normalizing an algorithm</a>, with
1012+
`alg` set to |alg| and `op` set to "`exportKey`".
1013+
</p>
1014+
</li>
1015+
<li>
1016+
<p>
1017+
If an error occurred, return false.
1018+
</p>
1019+
</li>
1020+
<li>
1021+
<p>
1022+
If the cryptographic algorithm identified by |normalizedAlgorithm|
1023+
does not support deriving a public key from a private key,
1024+
then return false.
1025+
</p>
1026+
</li>
1027+
<li>
1028+
<p>
1029+
Otherwise, return true.
1030+
</p>
1031+
</li>
1032+
</ol>
1033+
</dd>
1034+
</dl>
1035+
</li>
8711036
<li>
8721037
<p>
8731038
Let |normalizedAlgorithm| be the result of

0 commit comments

Comments
 (0)