Include usage in pubkey encoding
This commit is contained in:
+41
-6
@@ -11,13 +11,31 @@ export enum Usage {
|
||||
|
||||
export async function pubkey_toString(pubkey: CryptoKey): Promise<string> {
|
||||
log.trace('pubkey_toString')
|
||||
|
||||
const pubkey_buff = await crypto.subtle.exportKey('spki', pubkey)
|
||||
return a2b64(new Uint8Array(pubkey_buff))
|
||||
const pubkey_str = a2b64(new Uint8Array(pubkey_buff))
|
||||
|
||||
const usage = (pubkey.usages.includes('verify') ? Usage.sign : Usage.ecdh).toString()
|
||||
|
||||
return `${usage}${pubkey_str}`
|
||||
}
|
||||
export async function pubkey_fromString(pubkey_str: string, usage: Usage): Promise<CryptoKey | null> {
|
||||
export async function pubkey_fromString(pubkey_str: string): Promise<CryptoKey | null> {
|
||||
log.trace('pubkey_fromString')
|
||||
|
||||
const pubkey = b642a(pubkey_str)
|
||||
let usage: Usage;
|
||||
const c = pubkey_str.at(0)
|
||||
if (c === undefined) {
|
||||
log.warn('Empty string ?')
|
||||
return null
|
||||
} else if (c === Usage.sign.toString()) usage = Usage.sign
|
||||
else if (c === Usage.ecdh.toString()) usage = Usage.ecdh
|
||||
else {
|
||||
log.warn('Unknown usage encoded')
|
||||
log.debug('Usage :', c)
|
||||
return null
|
||||
}
|
||||
|
||||
const pubkey = b642a(pubkey_str.slice(1))
|
||||
if (pubkey === null) return null
|
||||
|
||||
try {
|
||||
@@ -37,15 +55,32 @@ export async function pubkey_fromString(pubkey_str: string, usage: Usage): Promi
|
||||
|
||||
export async function pubkey_toBytes(pubkey: CryptoKey): Promise<Uint8Array> {
|
||||
log.trace('pubkey_toBytes')
|
||||
return new Uint8Array(await crypto.subtle.exportKey('raw', pubkey))
|
||||
|
||||
const buf = new Uint8Array(await crypto.subtle.exportKey('raw', pubkey))
|
||||
const usage = pubkey.usages.includes('verify') ? Usage.sign : Usage.ecdh
|
||||
|
||||
return new Uint8Array([usage, ...buf])
|
||||
}
|
||||
export async function pubkey_fromBytes(pubkey: Uint8Array, usage: Usage): Promise<CryptoKey | null> {
|
||||
export async function pubkey_fromBytes(pubkey: Uint8Array): Promise<CryptoKey | null> {
|
||||
log.trace('pubkey_fromBytes')
|
||||
|
||||
let usage: Usage;
|
||||
const o = pubkey.at(0)
|
||||
if (o === undefined) {
|
||||
log.warn('Empty array ?')
|
||||
return null
|
||||
} else if (o === Usage.sign) usage = Usage.sign
|
||||
else if (o === Usage.ecdh) usage = Usage.ecdh
|
||||
else {
|
||||
log.warn('Unknown usage encoded')
|
||||
log.debug('Usage :', o)
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
return await crypto.subtle.importKey(
|
||||
'raw',
|
||||
pubkey,
|
||||
pubkey.slice(1),
|
||||
usage === Usage.ecdh ? ECDH_PARAMETERS() : SIGNATURE_KEY(),
|
||||
true,
|
||||
usage === Usage.ecdh ? [] : ['verify']
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ export default class PrivateBox {
|
||||
log.warn('Data too short to contain pubkey')
|
||||
return null
|
||||
}
|
||||
const pubkey = await pubkey_fromBytes(pubkey_buff, Usage.ecdh)
|
||||
const pubkey = await pubkey_fromBytes(pubkey_buff)
|
||||
if (pubkey === null) return null
|
||||
|
||||
const box = SecretBox.fromBytes(data.slice(1 + length))
|
||||
@@ -88,6 +88,6 @@ export default class PrivateBox {
|
||||
return await misc.pubkey_toString(pubkey)
|
||||
}
|
||||
public static async pubkey_fromString(pubkey: string): Promise<CryptoKey | null> {
|
||||
return await misc.pubkey_fromString(pubkey, misc.Usage.ecdh)
|
||||
return await misc.pubkey_fromString(pubkey)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -63,6 +63,6 @@ export default class PrivateWrap {
|
||||
return await misc.pubkey_toString(pubkey)
|
||||
}
|
||||
public static async pubkey_fromString(pubkey: string): Promise<CryptoKey | null> {
|
||||
return await misc.pubkey_fromString(pubkey, misc.Usage.ecdh)
|
||||
return await misc.pubkey_fromString(pubkey)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ export async function pubkey_toString(pubkey: CryptoKey): Promise<string> {
|
||||
return await misc.pubkey_toString(pubkey)
|
||||
}
|
||||
export async function pubkey_fromString(pubkey: string): Promise<CryptoKey | null> {
|
||||
return await misc.pubkey_fromString(pubkey, misc.Usage.sign)
|
||||
return await misc.pubkey_fromString(pubkey)
|
||||
}
|
||||
|
||||
export function signature_toString(signature: Uint8Array): string {
|
||||
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
import {expect, test} from 'bun:test'
|
||||
import {PrivateBox, PrivateWrap, SecretBox, signature} from '..'
|
||||
import {pubkey_fromBytes, pubkey_fromString, pubkey_toBytes, pubkey_toString, Usage} from '../src/misc'
|
||||
import {pubkey_fromBytes, pubkey_fromString, pubkey_toBytes, pubkey_toString} from '../src/misc'
|
||||
|
||||
test('Private box', async () => {
|
||||
const message = crypto.getRandomValues(new Uint8Array(8))
|
||||
const k = await PrivateBox.gen(false)
|
||||
|
||||
const ser = await pubkey_toString(k.publicKey)
|
||||
const de = await pubkey_fromString(ser, Usage.ecdh)
|
||||
const de = await pubkey_fromString(ser)
|
||||
expect(de).not.toBeNull()
|
||||
|
||||
const box = await PrivateBox.encrypt(message, de!)
|
||||
@@ -19,7 +19,7 @@ test('Private wrap', async () => {
|
||||
const k = await PrivateWrap.gen(false)
|
||||
|
||||
const ser = await pubkey_toString(k.publicKey)
|
||||
const de = await pubkey_fromString(ser, Usage.ecdh)
|
||||
const de = await pubkey_fromString(ser)
|
||||
expect(de).not.toBeNull()
|
||||
|
||||
const message = crypto.getRandomValues(new Uint8Array(8))
|
||||
@@ -42,7 +42,7 @@ test('Signature', async () => {
|
||||
expect(signed).not.toBeNull()
|
||||
|
||||
const ser = await pubkey_toString(k.publicKey)
|
||||
const de = await pubkey_fromString(ser, Usage.sign)
|
||||
const de = await pubkey_fromString(ser)
|
||||
expect(de).not.toBeNull()
|
||||
|
||||
const verification = await signature.verify(message, de!, signed!)
|
||||
@@ -55,7 +55,7 @@ test('Byte serialization', async () => {
|
||||
expect(signed).not.toBeNull()
|
||||
|
||||
const ser = await pubkey_toBytes(k.publicKey)
|
||||
const de = await pubkey_fromBytes(ser, Usage.sign)
|
||||
const de = await pubkey_fromBytes(ser)
|
||||
expect(de).not.toBeNull()
|
||||
|
||||
const verification = await signature.verify(message, de!, signed!)
|
||||
|
||||
Reference in New Issue
Block a user