Implement SecretWrap
ci/woodpecker/push/test Pipeline failed

Closes #6
This commit is contained in:
2024-05-14 22:29:09 +02:00
parent 528ccbdad7
commit ece4034764
3 changed files with 188 additions and 0 deletions
+1
View File
@@ -2,3 +2,4 @@ export {PrivateBox} from './asymmetric'
export {SecretBox} from './symmetric'
export {PwdBox} from './pwd'
export {PrivateWrap} from './private-wrap'
export {SecretWrap} from './secret-wrap'
+85
View File
@@ -0,0 +1,85 @@
import {Result} from 'result'
import * as misc from 'misc'
export type Key = CryptoKey
export class SecretWrap {
private constructor(
private readonly wrapped_key: Uint8Array,
private readonly algorithm: Algorithm,
private readonly usage: KeyUsage[],
private readonly format: KeyFormat,
private readonly iv: Uint8Array) {}
public static async gen_key(extractable: boolean = false) : Promise<Key> {
return crypto.subtle.generateKey(
{name: 'AES-GCM', length: 256},
extractable,
['wrapKey', 'unwrapKey']
)
}
public static async wrap_key(wrapping_key: Key, key_to_wrap: CryptoKey) : Promise<Result<SecretWrap>> {
const format = key_to_wrap.type === "secret" ? "raw" : "pkcs8"
const iv = crypto.getRandomValues(new Uint8Array(12))
try {
const wrapped_key = await crypto.subtle.wrapKey(
format,
key_to_wrap,
wrapping_key,
{
name: 'AES-GCM',
iv,
}
)
return Result.ok(new SecretWrap(new Uint8Array(wrapped_key), key_to_wrap.algorithm, key_to_wrap.usages, format, iv))
} catch (_) {}
return Result.error([])
}
public async unwrap(wrapping_key: Key) : Promise<Result<CryptoKey>> {
try {
const key = await crypto.subtle.unwrapKey(
this.format,
this.wrapped_key,
wrapping_key,
{
name: 'AES-GCM',
iv: this.iv,
},
this.algorithm,
true,
this.usage,
)
return Result.ok(key)
} catch (_) {}
return Result.error([])
}
public toString() : string {
const wrapped_key = misc.a2b64(this.wrapped_key)
const iv = misc.a2b64(this.iv)
return JSON.stringify({
wrapped_key,
algorithm: this.algorithm,
usage: this.usage,
format: this.format,
iv,
})
}
public static fromString(s: string) : Result<SecretWrap> {
const {iv: iv64, wrapped_key: wrapped_key64, algorithm, usage, format}: {wrapped_key: string, algorithm: Algorithm, usage: KeyUsage[], format: KeyFormat, iv: string} = JSON.parse(s)
const iv = misc.b642a(iv64)
if (iv.error()) return Result.error([])
const wrapped_key = misc.b642a(wrapped_key64)
if (wrapped_key.error()) return Result.error([])
return Result.ok(new SecretWrap(wrapped_key.unwrap(), algorithm, usage, format, iv.unwrap()))
}
}