55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
|
// This software may be modified and distributed under the terms
|
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
|
|
|
import { assert, stringToU8a, u8aFixLength } from '@polkadot/util';
|
|
import { naclDecrypt } from '@polkadot/util-crypto';
|
|
import { PairInfo } from './types';
|
|
|
|
import { NONCE_LENGTH, PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH } from './defaults';
|
|
|
|
const SEED_OFFSET = PKCS8_HEADER.length;
|
|
|
|
type DecodeResult = PairInfo & {
|
|
secretKey: Uint8Array;
|
|
};
|
|
|
|
export default function decode (passphrase?: string, encrypted?: Uint8Array | null): DecodeResult {
|
|
assert(encrypted, 'No encrypted data available to decode');
|
|
|
|
const encoded = passphrase
|
|
? (naclDecrypt(
|
|
encrypted.subarray(NONCE_LENGTH),
|
|
encrypted.subarray(0, NONCE_LENGTH),
|
|
u8aFixLength(stringToU8a(passphrase), 256, true)
|
|
) as Uint8Array)
|
|
: encrypted;
|
|
|
|
assert(encoded, 'Unable to unencrypt using the supplied passphrase');
|
|
|
|
const header = encoded.subarray(0, PKCS8_HEADER.length);
|
|
|
|
assert(header.toString() === PKCS8_HEADER.toString(), 'Invalid Pkcs8 header found in body');
|
|
|
|
let secretKey = encoded.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH);
|
|
let divOffset = SEED_OFFSET + SEC_LENGTH;
|
|
let divider = encoded.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
|
|
|
// old-style, we have the seed here
|
|
if (divider.toString() !== PKCS8_DIVIDER.toString()) {
|
|
divOffset = SEED_OFFSET + SEED_LENGTH;
|
|
secretKey = encoded.subarray(SEED_OFFSET, divOffset);
|
|
divider = encoded.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
|
}
|
|
|
|
assert(divider.toString() === PKCS8_DIVIDER.toString(), 'Invalid Pkcs8 divider found in body');
|
|
|
|
const pubOffset = divOffset + PKCS8_DIVIDER.length;
|
|
const publicKey = encoded.subarray(pubOffset, pubOffset + PUB_LENGTH);
|
|
|
|
return {
|
|
publicKey,
|
|
secretKey
|
|
};
|
|
}
|