Skip to content

Commit

Permalink
feat: add more asymmetric JWS algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Feb 9, 2023
1 parent b587651 commit af43ec7
Show file tree
Hide file tree
Showing 10 changed files with 379 additions and 125 deletions.
51 changes: 47 additions & 4 deletions .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,22 @@ jobs:
client_auth_type: none
plan: oidcc-client-test-plan

# ES256
- algorithm: ES256
# RS256
- algorithm: RS256
plan: oidcc-client-test-plan
variant:
request_type: request_object
client_auth_type: private_key_jwt

# RS256
- algorithm: RS256
# RS384
- algorithm: RS384
plan: oidcc-client-test-plan
variant:
request_type: request_object
client_auth_type: private_key_jwt

# RS512
- algorithm: RS512
plan: oidcc-client-test-plan
variant:
request_type: request_object
Expand All @@ -120,6 +127,42 @@ jobs:
request_type: request_object
client_auth_type: private_key_jwt

# PS384
- algorithm: PS384
plan: oidcc-client-test-plan
variant:
request_type: request_object
client_auth_type: private_key_jwt

# PS512
- algorithm: PS512
plan: oidcc-client-test-plan
variant:
request_type: request_object
client_auth_type: private_key_jwt

# ES256
- algorithm: ES256
plan: oidcc-client-test-plan
variant:
request_type: request_object
client_auth_type: private_key_jwt

# TODO: https://gitlab.com/openid/conformance-suite/-/issues/1129
# # ES384
# - algorithm: ES384
# plan: oidcc-client-test-plan
# variant:
# request_type: request_object
# client_auth_type: private_key_jwt

# # ES512
# - algorithm: ES512
# plan: oidcc-client-test-plan
# variant:
# request_type: request_object
# client_auth_type: private_key_jwt

# EdDSA
- algorithm: EdDSA
plan: oidcc-client-test-plan
Expand Down
48 changes: 41 additions & 7 deletions conformance/ava.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,21 @@ async function RS256() {
kid: crypto.randomUUID(),
}
}

async function RS384() {
return { ...(await RS256()), alg: 'RS384' }
}
async function RS512() {
return { ...(await RS256()), alg: 'RS512' }
}
async function PS256() {
return {
...(await RS256()),
alg: 'PS256',
}
return { ...(await RS256()), alg: 'PS256' }
}
async function PS384() {
return { ...(await RS256()), alg: 'PS384' }
}
async function PS512() {
return { ...(await RS256()), alg: 'PS512' }
}

async function ES256() {
return {
...exportPrivate(await generateKeyPair('ec', { namedCurve: 'P-256' })),
Expand All @@ -50,7 +57,22 @@ async function ES256() {
kid: crypto.randomUUID(),
}
}

async function ES384() {
return {
...exportPrivate(await generateKeyPair('ec', { namedCurve: 'P-384' })),
use: 'sig',
alg: 'ES384',
kid: crypto.randomUUID(),
}
}
async function ES512() {
return {
...exportPrivate(await generateKeyPair('ec', { namedCurve: 'P-521' })),
use: 'sig',
alg: 'ES512',
kid: crypto.randomUUID(),
}
}
async function EdDSA() {
return {
...exportPrivate(await generateKeyPair('ed25519')),
Expand All @@ -64,10 +86,22 @@ async function generate() {
switch (JWS_ALGORITHM) {
case 'PS256':
return Promise.all([PS256()])
case 'PS384':
return Promise.all([PS384()])
case 'PS512':
return Promise.all([PS512()])
case 'RS256':
return Promise.all([RS256()])
case 'RS384':
return Promise.all([RS384()])
case 'RS512':
return Promise.all([RS512()])
case 'ES256':
return Promise.all([ES256()])
case 'ES384':
return Promise.all([ES384()])
case 'ES512':
return Promise.all([ES512()])
case 'EdDSA':
return Promise.all([EdDSA()])
default:
Expand Down
39 changes: 17 additions & 22 deletions conformance/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,24 @@ switch (plan.name) {
throw new Error()
}

const es = (namedCurve: string): EcKeyImportParams => ({ name: 'ECDSA', namedCurve })
const rs = (hash: string): RsaHashedImportParams => ({
name: 'RSASSA-PKCS1-v1_5',
hash: { name: hash },
})
const ps = (hash: string): RsaHashedImportParams => ({ ...rs(hash), name: 'RSA-PSS' })

const algorithms: Map<string, RsaHashedImportParams | EcKeyImportParams | Algorithm> = new Map([
[
'PS256',
{
name: 'RSA-PSS',
hash: { name: 'SHA-256' },
},
],
[
'ES256',
{
name: 'ECDSA',
namedCurve: 'P-256',
},
],
[
'RS256',
{
name: 'RSASSA-PKCS1-v1_5',
hash: { name: 'SHA-256' },
},
],
['EdDSA', { name: 'Ed25519' }],
['PS256', ps('SHA-256')],
['PS384', ps('SHA-384')],
['PS512', ps('SHA-512')],
['RS256', rs('SHA-256')],
['RS384', rs('SHA-384')],
['RS512', rs('SHA-512')],
['ES256', es('P-256')],
['ES384', es('P-384')],
['ES512', es('P-521')],
['EdDSA', <Algorithm>{ name: 'Ed25519' }],
])

function importPrivateKey(alg: string, jwk: JsonWebKey) {
Expand Down
9 changes: 9 additions & 0 deletions docs/interfaces/GenerateKeyPairOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,20 @@

### Properties

- [crv](GenerateKeyPairOptions.md#crv)
- [extractable](GenerateKeyPairOptions.md#extractable)
- [modulusLength](GenerateKeyPairOptions.md#moduluslength)

## Properties

### crv

`Optional` **crv**: ``"Ed25519"`` \| ``"Ed448"``

(EdDSA algorithms only) The EdDSA sub-type. Default is `Ed25519`.

___

### extractable

`Optional` **extractable**: `boolean`
Expand Down
54 changes: 45 additions & 9 deletions docs/types/JWSAlgorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,71 @@

[💗 Help the project](https://github.com/sponsors/panva)

Ƭ **JWSAlgorithm**: ``"PS256"`` \| ``"ES256"`` \| ``"RS256"`` \| ``"EdDSA"``
Ƭ **JWSAlgorithm**: ``"PS256"`` \| ``"ES256"`` \| ``"RS256"`` \| ``"EdDSA"`` \| ``"ES384"`` \| ``"PS384"`` \| ``"RS384"`` \| ``"ES512"`` \| ``"PS512"`` \| ``"RS512"``

Supported JWS `alg` Algorithm identifiers.

**`example`** CryptoKey algorithm for the `PS256` JWS Algorithm Identifier
**`example`** CryptoKey algorithm for the `PS256`, `PS384`, or `PS512` JWS Algorithm Identifiers

```ts
interface Ps256Algorithm extends RsaHashedKeyAlgorithm {
interface RSAPSSAlgorithm extends RsaHashedKeyAlgorithm {
name: 'RSA-PSS'
hash: { name: 'SHA-256' | 'SHA-384' | 'SHA-512' }
}

interface PS256 extends RSAPSSAlgorithm {
hash: { name: 'SHA-256' }
}

interface PS384 extends RSAPSSAlgorithm {
hash: { name: 'SHA-384' }
}

interface PS512 extends RSAPSSAlgorithm {
hash: { name: 'SHA-512' }
}
```

**`example`** CryptoKey algorithm for the `ES256` JWS Algorithm Identifier
**`example`** CryptoKey algorithm for the `ES256`, `ES384`, or `ES512` JWS Algorithm Identifiers

```ts
interface Es256Algorithm extends EcKeyAlgorithm {
interface ECDSAAlgorithm extends EcKeyAlgorithm {
name: 'ECDSA'
namedCurve: 'P-256' | 'P-384' | 'P-521'
}

interface ES256 extends ECDSAAlgorithm {
namedCurve: 'P-256'
}

interface ES384 extends ECDSAAlgorithm {
namedCurve: 'P-384'
}

interface ES512 extends ECDSAAlgorithm {
namedCurve: 'P-521'
}
```

**`example`** CryptoKey algorithm for the `RS256` JWS Algorithm Identifier
**`example`** CryptoKey algorithm for the `RS256`, `RS384`, or `RS512` JWS Algorithm Identifiers

```ts
interface Rs256Algorithm extends RsaHashedKeyAlgorithm {
interface ECDSAAlgorithm extends RsaHashedKeyAlgorithm {
name: 'RSASSA-PKCS1-v1_5'
hash: { name: 'SHA-256' | 'SHA-384' | 'SHA-512' }
}

interface RS256 extends ECDSAAlgorithm {
hash: { name: 'SHA-256' }
}

interface RS384 extends ECDSAAlgorithm {
hash: { name: 'SHA-384' }
}

interface RS512 extends ECDSAAlgorithm {
hash: { name: 'SHA-512' }
}
```

**`example`** CryptoKey algorithm for the `EdDSA` JWS Algorithm Identifier (Experimental)
Expand All @@ -40,7 +76,7 @@ Cryptography API](https://wicg.github.io/webcrypto-secure-curves/) proposal whic
widely adopted. If the proposal changes this implementation will follow up with a minor release.

```ts
interface EdDSAAlgorithm extends KeyAlgorithm {
name: 'Ed25519'
interface EdDSA extends KeyAlgorithm {
name: 'Ed25519' | 'Ed448'
}
```

0 comments on commit af43ec7

Please sign in to comment.