60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import logger from 'log'
|
|
import {DHusage, ecdh} from './kdf'
|
|
import SecretWrap from './secret-wrap'
|
|
import * as misc from './misc'
|
|
import * as consts from './const'
|
|
|
|
const log = logger('crypto:private-wrap')
|
|
|
|
export default class PrivateWrap {
|
|
private constructor(
|
|
private readonly box: SecretWrap,
|
|
private readonly pubkey: CryptoKey
|
|
) {}
|
|
|
|
public static async gen(extractable: boolean = true): Promise<CryptoKeyPair> {
|
|
log.trace('generate keypair')
|
|
return await crypto.subtle.generateKey(consts.ECDH, extractable, ['deriveKey']) as CryptoKeyPair
|
|
}
|
|
|
|
public static async wrap(data: CryptoKey, pubkey: CryptoKey): Promise<PrivateWrap> {
|
|
log.trace('wrap')
|
|
const tmp_keypair = await PrivateWrap.gen()
|
|
const kd = await ecdh(tmp_keypair.privateKey, pubkey, DHusage.wrap)
|
|
const box = await SecretWrap.wrap(data, kd)
|
|
return new this(box, tmp_keypair.publicKey)
|
|
}
|
|
public async unwrap(privkey: CryptoKey): Promise<CryptoKey | null> {
|
|
log.trace('unwrap')
|
|
const kd = await ecdh(privkey, this.pubkey, DHusage.wrap)
|
|
return await this.box.unwrap(kd)
|
|
}
|
|
|
|
public async toString(): Promise<string> {
|
|
log.trace('toString')
|
|
const pubkey = await PrivateWrap.pubkey_toString(this.pubkey)
|
|
const box = this.box.toString()
|
|
return `${pubkey}.${box}`
|
|
}
|
|
public static async fromString(data: string): Promise<PrivateWrap | null> {
|
|
log.trace('fromString')
|
|
|
|
const parts = data.split('.')
|
|
if (parts.length < 2) return null
|
|
|
|
const pubkey = await PrivateWrap.pubkey_fromString(parts[0])
|
|
if (pubkey === null) return null
|
|
const box = SecretWrap.fromString(parts.slice(1).join('.'))
|
|
if (box === null) return null
|
|
|
|
return new PrivateWrap(box, pubkey)
|
|
}
|
|
|
|
public static async pubkey_toString(pubkey: CryptoKey): Promise<string> {
|
|
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)
|
|
}
|
|
}
|