mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-11-24 14:35:51 +00:00
refactor: gnu s2k type to its own class
This commit is contained in:
parent
774e619bae
commit
61866e166e
@ -101,22 +101,8 @@ class GenericS2K {
|
|||||||
this.c = bytes[i++];
|
this.c = bytes[i++];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'gnu':
|
|
||||||
if (util.uint8ArrayToString(bytes.subarray(i, i + 3)) === 'GNU') {
|
|
||||||
i += 3; // GNU
|
|
||||||
const gnuExtType = 1000 + bytes[i++];
|
|
||||||
if (gnuExtType === 1001) {
|
|
||||||
this.type = 'gnu-dummy';
|
|
||||||
// GnuPG extension mode 1001 -- don't write secret key at all
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedError('Unknown s2k gnu protection mode.');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedError('Unknown s2k type.');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
throw new UnsupportedError('Unknown s2k type.'); // unreachable
|
throw new UnsupportedError('Unknown s2k type.'); // unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,9 +114,6 @@ class GenericS2K {
|
|||||||
* @returns {Uint8Array} Binary representation of s2k.
|
* @returns {Uint8Array} Binary representation of s2k.
|
||||||
*/
|
*/
|
||||||
write(): Uint8Array {
|
write(): Uint8Array {
|
||||||
if (this.type === 'gnu-dummy') {
|
|
||||||
return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
|
|
||||||
}
|
|
||||||
const arr = [new Uint8Array([enums.write(enums.s2k, this.type), this.algorithm])];
|
const arr = [new Uint8Array([enums.write(enums.s2k, this.type), this.algorithm])];
|
||||||
|
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
@ -143,8 +126,6 @@ class GenericS2K {
|
|||||||
this.salt &&arr.push(this.salt);
|
this.salt &&arr.push(this.salt);
|
||||||
arr.push(new Uint8Array([this.c]));
|
arr.push(new Uint8Array([this.c]));
|
||||||
break;
|
break;
|
||||||
case 'gnu':
|
|
||||||
throw new Error('GNU s2k type not supported.');
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Unknown s2k type.');
|
throw new Error('Unknown s2k type.');
|
||||||
}
|
}
|
||||||
@ -187,8 +168,6 @@ class GenericS2K {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'gnu':
|
|
||||||
throw new Error('GNU s2k type not supported.');
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Unknown s2k type.');
|
throw new Error('Unknown s2k type.');
|
||||||
}
|
}
|
||||||
|
|||||||
120
src/type/s2k/gnu.ts
Normal file
120
src/type/s2k/gnu.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||||
|
// Copyright (C) 2011 Recurity Labs GmbH
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3.0 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the String-to-key specifier
|
||||||
|
*
|
||||||
|
* {@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC4880 3.7}:
|
||||||
|
* String-to-key (S2K) specifiers are used to convert passphrase strings
|
||||||
|
* into symmetric-key encryption/decryption keys. They are used in two
|
||||||
|
* places, currently: to encrypt the secret part of private keys in the
|
||||||
|
* private keyring, and to convert passphrases to encryption keys for
|
||||||
|
* symmetrically encrypted messages.
|
||||||
|
* @module type/s2k
|
||||||
|
*/
|
||||||
|
|
||||||
|
import defaultConfig from '../../config';
|
||||||
|
import crypto from '../../crypto';
|
||||||
|
import enums from '../../enums';
|
||||||
|
import { UnsupportedError } from '../../packet/packet';
|
||||||
|
import util from '../../util';
|
||||||
|
|
||||||
|
class GnuS2k {
|
||||||
|
algorithm: number;
|
||||||
|
type: string;
|
||||||
|
c: number;
|
||||||
|
/**
|
||||||
|
* @param {Object} [config] - Full configuration, defaults to openpgp.config
|
||||||
|
*/
|
||||||
|
constructor(config = defaultConfig) {
|
||||||
|
/**
|
||||||
|
* Hash function identifier, or 0 for gnu-dummy keys
|
||||||
|
* @type {module:enums.hash | 0}
|
||||||
|
*/
|
||||||
|
this.algorithm = enums.hash.sha256;
|
||||||
|
/**
|
||||||
|
* enums.s2k identifier or 'gnu-dummy'
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
this.type = 'gnu';
|
||||||
|
/**
|
||||||
|
* @type {Integer}
|
||||||
|
*/
|
||||||
|
this.c = config.s2kIterationCountByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}).
|
||||||
|
* @param {Uint8Array} bytes - Payload of string-to-key specifier
|
||||||
|
* @returns {Integer} Actual length of the object.
|
||||||
|
*/
|
||||||
|
read(bytes: Uint8Array): Number {
|
||||||
|
let i = 0;
|
||||||
|
this.algorithm = bytes[i++];
|
||||||
|
if (util.uint8ArrayToString(bytes.subarray(i, i + 3)) === 'GNU') {
|
||||||
|
i += 3; // GNU
|
||||||
|
const gnuExtType = 1000 + bytes[i++];
|
||||||
|
if (gnuExtType === 1001) {
|
||||||
|
this.type = 'gnu-dummy';
|
||||||
|
// GnuPG extension mode 1001 -- don't write secret key at all
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedError('Unknown s2k gnu protection mode.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedError('Unknown s2k type.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes s2k information
|
||||||
|
* @returns {Uint8Array} Binary representation of s2k.
|
||||||
|
*/
|
||||||
|
write(): Uint8Array {
|
||||||
|
if (this.type === 'gnu-dummy') {
|
||||||
|
return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
|
||||||
|
} else {
|
||||||
|
throw new Error('GNU s2k type not supported.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces a key using the specified passphrase and the defined
|
||||||
|
* hashAlgorithm
|
||||||
|
* @param {String} passphrase - Passphrase containing user input
|
||||||
|
* @returns {Promise<Uint8Array>} Produced key with a length corresponding to.
|
||||||
|
* hashAlgorithm hash length
|
||||||
|
* @async
|
||||||
|
*/
|
||||||
|
async produceKey(passphrase: string, numBytes: number): Promise<Uint8Array> {
|
||||||
|
const arr: number[] = [];
|
||||||
|
let rlength = 0;
|
||||||
|
|
||||||
|
while (rlength < numBytes) {
|
||||||
|
if (this.type !== 'gnu') {
|
||||||
|
throw new Error('Unknown s2k type.');
|
||||||
|
} else {
|
||||||
|
throw new Error('GNU s2k type not supported.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.concatUint8Array(arr).subarray(0, numBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GnuS2k;
|
||||||
@ -3,6 +3,7 @@ import Argon2S2K, { Argon2OutOfMemoryError } from './argon2';
|
|||||||
import GenericS2K from './generic';
|
import GenericS2K from './generic';
|
||||||
import enums from '../../enums';
|
import enums from '../../enums';
|
||||||
import { UnsupportedError } from '../../packet/packet';
|
import { UnsupportedError } from '../../packet/packet';
|
||||||
|
import GnuS2K from './gnu';
|
||||||
|
|
||||||
const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterated]);
|
const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterated]);
|
||||||
|
|
||||||
@ -13,12 +14,13 @@ const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterat
|
|||||||
* @returns {Object} New s2k object
|
* @returns {Object} New s2k object
|
||||||
* @throws {Error} for unknown or unsupported types
|
* @throws {Error} for unknown or unsupported types
|
||||||
*/
|
*/
|
||||||
export function newS2KFromType (type: number, config = defaultConfig): Argon2S2K | GenericS2K {
|
export function newS2KFromType (type: number, config = defaultConfig): Argon2S2K | GenericS2K | GnuS2K {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case enums.s2k.gnu:
|
||||||
|
return new GnuS2K(config);
|
||||||
case enums.s2k.argon2:
|
case enums.s2k.argon2:
|
||||||
return new Argon2S2K(config);
|
return new Argon2S2K(config);
|
||||||
case enums.s2k.iterated:
|
case enums.s2k.iterated:
|
||||||
case enums.s2k.gnu:
|
|
||||||
case enums.s2k.salted:
|
case enums.s2k.salted:
|
||||||
case enums.s2k.simple:
|
case enums.s2k.simple:
|
||||||
return new GenericS2K(type, config);
|
return new GenericS2K(type, config);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user