Rework API
This commit is contained in:
+21
-37
@@ -1,68 +1,52 @@
|
||||
import {a2b64, b642a} from 'misc'
|
||||
import logger from 'log'
|
||||
|
||||
import {SecretWrap} from './secret-wrap'
|
||||
import {ecdh} from './kdf'
|
||||
import {DHusage, ecdh} from './kdf'
|
||||
import SecretWrap from './secret-wrap'
|
||||
import {pubkey_fromString, pubkey_toString, Usage} from './misc'
|
||||
import * as consts from './const'
|
||||
|
||||
const log = logger('crypto:private-wrap')
|
||||
|
||||
const algorithm = {
|
||||
name: 'ECDH',
|
||||
namedCurve: 'P-521'
|
||||
}
|
||||
export default class PrivateWrap {
|
||||
private constructor(
|
||||
private readonly box: SecretWrap,
|
||||
private readonly pubkey: CryptoKey
|
||||
) {}
|
||||
|
||||
export class PrivateWrap {
|
||||
private constructor(private readonly box: SecretWrap, private readonly pubkey: CryptoKey) {}
|
||||
|
||||
public static gen_keypair(extractable: boolean = true): Promise<CryptoKeyPair> {
|
||||
public static gen(extractable: boolean = true): Promise<CryptoKeyPair> {
|
||||
log.trace('generate keypair')
|
||||
return crypto.subtle.generateKey(algorithm, extractable, ['deriveKey'])
|
||||
return crypto.subtle.generateKey(consts.ECDH, extractable, ['deriveKey']) as Promise<CryptoKeyPair>
|
||||
}
|
||||
|
||||
public static async encrypt(data: CryptoKey, pubkey: CryptoKey): Promise<PrivateWrap> {
|
||||
log.trace('encrypt')
|
||||
const k = await this.gen_keypair()
|
||||
const kd = await ecdh(k.privateKey, pubkey)
|
||||
const tmp_keypair = await PrivateWrap.gen()
|
||||
const kd = await ecdh(tmp_keypair.privateKey, pubkey, DHusage.wrap)
|
||||
const box = await SecretWrap.encrypt(data, kd)
|
||||
return new this(box, k.publicKey)
|
||||
return new this(box, tmp_keypair.publicKey)
|
||||
}
|
||||
public async decrypt(privkey: CryptoKey): Promise<CryptoKey> {
|
||||
public async decrypt(privkey: CryptoKey): Promise<CryptoKey | null> {
|
||||
log.trace('decrypt')
|
||||
const kd = await ecdh(privkey, this.pubkey)
|
||||
const kd = await ecdh(privkey, this.pubkey, DHusage.wrap)
|
||||
return this.box.decrypt(kd)
|
||||
}
|
||||
|
||||
public async toString(): Promise<string> {
|
||||
log.trace('toString')
|
||||
const pubkey = await PrivateWrap.publicKey_toString(this.pubkey)
|
||||
const pubkey = await 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('.', 2)
|
||||
if (parts.length !== 2) return null
|
||||
const parts = data.split('.')
|
||||
if (parts.length < 2) return null
|
||||
|
||||
const pubkey = await this.publicKey_fromString(parts[0])
|
||||
const pubkey = await pubkey_fromString(parts[0], Usage.ecdh)
|
||||
if (pubkey === null) return null
|
||||
const box = SecretWrap.fromString(parts[1])
|
||||
const box = SecretWrap.fromString(parts.slice(1).join("."))
|
||||
if (box === null) return null
|
||||
|
||||
return new PrivateWrap(box, pubkey)
|
||||
}
|
||||
|
||||
public static async publicKey_toString(publicKey: CryptoKey): Promise<string> {
|
||||
const pubkey_spki = await crypto.subtle.exportKey('spki', publicKey)
|
||||
return a2b64(new Uint8Array(pubkey_spki))
|
||||
}
|
||||
public static async publicKey_fromString(data: string): Promise<CryptoKey | null> {
|
||||
const pubkey_str = b642a(data)
|
||||
if (pubkey_str.is_err()) return null
|
||||
try {
|
||||
return crypto.subtle.importKey('spki', pubkey_str.unwrap(), algorithm, true, [])
|
||||
} catch(e) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user