V0.6.9 Arroyo Toad

Added support for P256 curve and suppressed the one for P521 for testing reasons
This commit is contained in:
Christian Risi
2024-12-07 18:00:35 +00:00
parent e9abeb9bb6
commit fa71d33a53
13 changed files with 169 additions and 27 deletions

View File

@@ -11,7 +11,7 @@ export class Message {
public deviceType: DeviceType;
public signatureType: SignatureType;
public timestamp: bigint;
public timestamp: number;
public deviceID: bigint;
public location: DeviceLocation;
public fields: Field[];
@@ -23,7 +23,7 @@ export class Message {
deviceType: DeviceType,
RESERVED: number,
signatureType: SignatureType,
timestamp: bigint,
timestamp: number,
deviceID: bigint,
location: DeviceLocation,
fields: Field[],
@@ -50,7 +50,7 @@ Message ----------------------
\tDevice Type: \t${this.deviceType}
\tRESERVED: \t${this.RESERVED}
\tSignature Type: \t${this.signatureType}
\tTimestamp: \t${ new Date(Number(this.timestamp / 10000000n))}
\tTimestamp: \t${ new Date(this.timestamp * 1000)}
\tDevice ID: \t${this.deviceID}
\tLocation: \tX: ${this.location.x}\tY: ${this.location.y}\tZ: ${this.location.z}
\tFields: \n`;

View File

@@ -1,3 +1,5 @@
export enum SignatureType {
P521 = 10
P521 = 10,
P384 = 11,
P256 = 12,
}

View File

@@ -1 +1,2 @@
console.log("Hu")

View File

@@ -4,8 +4,10 @@ import { DeviceType } from "../enums/DeviceType.ts";
import { MessageType } from "../enums/MessageType.ts";
import { SignatureType } from "../enums/SignatureType.ts";
import { DeviceLocation } from "../classes/Location.ts";
import { signatureVerifierV1 } from "./signatureVerifier.ts";
import * as mod from "node:crypto";
export function deserializerV1(buffer: ArrayBuffer) {
export async function deserializerV1(buffer: ArrayBuffer, key: mod.webcrypto.CryptoKey) {
const version: number = new Uint8Array(buffer.slice(0, 1))[0];
// UGLY Force typecasting
@@ -31,7 +33,7 @@ export function deserializerV1(buffer: ArrayBuffer) {
] as keyof typeof SignatureType
];
const timestamp: bigint = new BigUint64Array(buffer.slice(8, 16))[0];
const timestamp: number = new Float64Array(buffer.slice(8, 16))[0];
// UGLY: sum the 2 bigints to a sing bigint
const deviceID_Buffer = new BigUint64Array(buffer.slice(16, 32));
@@ -44,7 +46,7 @@ export function deserializerV1(buffer: ArrayBuffer) {
let index = 56;
let MORE_FIELDS = true;
let fields: Field[] = Array<Field>();
const fields: Field[] = Array<Field>();
while (MORE_FIELDS) {
const nextchunk = new BigUint64Array(buffer.slice(index, index + 8))[0];
@@ -71,11 +73,19 @@ export function deserializerV1(buffer: ArrayBuffer) {
index += paddingBytes + 8;
const signatureStart = index
const msgBuffer = buffer.slice(0, signatureStart)
const signature = new Uint8Array(buffer.slice(index))
if (signature.length != signatureBytesMapper(signatureType)) {
throw new Error("This signature is not valid")
const result = await signatureVerifierV1(msgBuffer, signature, key)
if (!result) {
throw new Error("Invalid message")
}
return new Message(
version,
@@ -92,12 +102,5 @@ export function deserializerV1(buffer: ArrayBuffer) {
}
export function signatureBytesMapper(signatureType: SignatureType) {
switch (signatureType) {
case SignatureType.P521 : {
return 132
}
}
}

View File

@@ -0,0 +1,59 @@
import * as mod from "node:crypto";
import { atob } from "node:buffer";
/// Copy pasted from Mozilla
function str2ab(str: string) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
export async function signatureVerifierV1(
msgData: ArrayBuffer,
signature: ArrayBuffer,
Ku: mod.webcrypto.CryptoKey,
) {
// UGLY: Assuming ECDSA P-256
return await mod.subtle.verify(
{
name: "ECDSA",
hash: "SHA-256",
},
Ku,
signature,
msgData,
);
}
export async function pem2key(filePath: string) {
const publicKeyBytes = await Deno.readFile(filePath);
const pemKey = new TextDecoder().decode(publicKeyBytes);
// fetch the part of the PEM string between header and footer
const pemHeader = "-----BEGIN PUBLIC KEY-----";
const pemFooter = "-----END PUBLIC KEY-----";
const pemContents = pemKey.substring(
pemHeader.length,
pemKey.length - pemFooter.length - 1,
);
// base64 decode the string to get the binary data
// convert from a binary string to an ArrayBuffer
const a = atob(pemContents);
const binaryDer = str2ab(a);
// UGLY: Assuming P-256
return mod.subtle.importKey(
"spki",
binaryDer,
{
name: "ECDSA",
namedCurve: "P-256",
},
true,
["verify"],
);
}