Skip to content

Commit

Permalink
Add support for P-521 curve
Browse files Browse the repository at this point in the history
Sadly Deno doesn't support it.

See: denoland/deno#13449 (comment)
  • Loading branch information
wiktor-k committed Mar 7, 2024
1 parent 65704c7 commit afbfd06
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 6 deletions.
1 change: 1 addition & 0 deletions fixtures/p521.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Sure, here is P-265 fixture ;)
2 changes: 2 additions & 0 deletions fixtures/p521.txt.ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Deno doesn't support P-521 due to their underlying crypto lib not supporting it.
See: https://github.com/denoland/deno/issues/13449#issuecomment-1879050683
10 changes: 10 additions & 0 deletions fixtures/p521.txt.sig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAAKwAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQAAAI
UEABon2x0D7m1Dxnfxp9HhV3VddppTwwIpGxjj1u3ukoP/mEsH+LGMTu+ZMacofZpZRiGZ
5TyghUKep6pErZjffhnwAaMUI1M9kgK/QJVDpqiwiaRjRD4QXzVjxRhIsGPx11bCrxiuHJ
muoPPo8tibOuq8PHvYB9RIz3IZjy6BrV8w6cqlAAAABGZpbGUAAAAAAAAABnNoYTUxMgAA
AKcAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAIwAAABCAd0AAb8B0I3EziNuDnVnRKNk4t
3qtJqQ4w0fZhaguZ3LbSSwj4qAsIytsIdyD8MF04hm6lh+NzJa24Kt5uHSh7PbAAAAQgH+
fCBwwS5/AWWrtEdrlxK5Tu2pVFLofJRoO5mDn80pHidM8IHQhecJmGY02e/G5dUpSoY/q3
r6xnimpmfqKKrKUw==
-----END SSH SIGNATURE-----
22 changes: 18 additions & 4 deletions formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ export type Pubkey = {
key: Uint8Array;
toString(): string;
} | {
pk_algo: "ecdsa-sha2-nistp256" | "ecdsa-sha2-nistp384";
pk_algo:
| "ecdsa-sha2-nistp256"
| "ecdsa-sha2-nistp384"
| "ecdsa-sha2-nistp521";
curve: string;
point: Uint8Array;
toString(): string;
Expand Down Expand Up @@ -40,7 +43,8 @@ export function parsePubkey(
},
};
} else if (
pk_algo === "ecdsa-sha2-nistp256" || pk_algo === "ecdsa-sha2-nistp384"
pk_algo === "ecdsa-sha2-nistp256" || pk_algo === "ecdsa-sha2-nistp384" ||
pk_algo === "ecdsa-sha2-nistp521"
) {
const curve = publickey.readString().toString();
pubkey = {
Expand Down Expand Up @@ -91,7 +95,8 @@ export function convertPublicKey(publickey: Pubkey): {
format: "raw",
};
} else if (
pk_algo === "ecdsa-sha2-nistp256" || pk_algo === "ecdsa-sha2-nistp384"
pk_algo === "ecdsa-sha2-nistp256" || pk_algo === "ecdsa-sha2-nistp384" ||
pk_algo === "ecdsa-sha2-nistp521"
) {
if (publickey.point[0] !== 0x04) {
throw new Error("Only uncompressed (0x04) format is supported");
Expand All @@ -102,9 +107,12 @@ export function convertPublicKey(publickey: Pubkey): {
let crv;
if (pk_algo === "ecdsa-sha2-nistp256") {
crv = "P-256";
} else {
} else if (pk_algo === "ecdsa-sha2-nistp384") {
crv = "P-384";
}
{
crv = "P-521";
}
return {
keyData: {
kty: "EC",
Expand Down Expand Up @@ -142,6 +150,12 @@ export function convertAlgorithm(sig_algo: string) {
namedCurve: "P-384",
hash: { name: "SHA-384" },
};
} else if (sig_algo === "ecdsa-sha2-nistp521") {
return {
name: "ECDSA",
namedCurve: "P-521",
hash: { name: "SHA-512" },
};
} else {
throw new Error(`Unsupported algo: ${sig_algo}`);
}
Expand Down
3 changes: 2 additions & 1 deletion sig_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ export function parse(signature: DataView | string): Sig {
const sig_bytes = raw_signature.readString();
let bytes;
if (
sig_algo === "ecdsa-sha2-nistp256" || sig_algo === "ecdsa-sha2-nistp384"
sig_algo === "ecdsa-sha2-nistp256" || sig_algo === "ecdsa-sha2-nistp384" ||
sig_algo === "ecdsa-sha2-nistp512"
) {
let r = new Uint8Array(sig_bytes.readString().bytes());
if (r[0] === 0x00 && r.length % 2 == 1) {
Expand Down
9 changes: 8 additions & 1 deletion verifier_test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { assertEquals } from "https://deno.land/std@0.217.0/assert/mod.ts";
import { existsSync } from "https://deno.land/std@0.217.0/fs/mod.ts";
import { verify } from "./index.ts";
import { parse } from "./sig_parser.ts";

for await (const entry of Deno.readDir("fixtures")) {
if (entry.name.endsWith(".sig")) {
Deno.test(
{ permissions: { read: true, write: true, run: true }, name: entry.name },
{
permissions: { read: true, write: true, run: true },
ignore: existsSync(
`fixtures/${entry.name.replace(/\.sig$/, ".ignore")}`,
),
name: entry.name,
},
async () => {
const signature = parse(
await Deno.readTextFile(`fixtures/${entry.name}`),
Expand Down

0 comments on commit afbfd06

Please sign in to comment.