2018-05-15 11:15:31 +02:00
/ * *
* @ author tlwr [ toby @ toby . codes ]
* @ author Matt C [ matt @ artemisbot . uk ]
* @ author n1474335 [ n1474335 @ gmail . com ]
* @ copyright Crown Copyright 2017
* @ license Apache - 2.0
* /
2019-07-09 13:23:59 +02:00
import Operation from "../Operation.mjs" ;
2018-05-15 17:04:57 +02:00
import kbpgp from "kbpgp" ;
2019-07-09 13:23:59 +02:00
import { getSubkeySize , ASP } from "../lib/PGP.mjs" ;
2018-05-29 18:00:24 +02:00
import * as es6promisify from "es6-promisify" ;
const promisify = es6promisify . default ? es6promisify . default . promisify : es6promisify . promisify ;
2018-05-16 11:17:49 +02:00
2018-05-15 11:15:31 +02:00
/ * *
* Generate PGP Key Pair operation
* /
class GeneratePGPKeyPair extends Operation {
/ * *
* GeneratePGPKeyPair constructor
* /
constructor ( ) {
super ( ) ;
this . name = "Generate PGP Key Pair" ;
this . module = "PGP" ;
2021-02-01 20:15:32 +01:00
this . description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.<br><br>WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts." ;
2018-08-21 20:07:13 +02:00
this . infoURL = "https://wikipedia.org/wiki/Pretty_Good_Privacy" ;
2018-05-15 11:15:31 +02:00
this . inputType = "string" ;
this . outputType = "string" ;
this . args = [
{
"name" : "Key type" ,
"type" : "option" ,
2021-02-01 12:10:04 +01:00
"value" : [ "RSA-1024" , "RSA-2048" , "RSA-4096" , "ECC-256" , "ECC-384" , "ECC-521" ]
2018-05-15 11:15:31 +02:00
} ,
{
"name" : "Password (optional)" ,
"type" : "string" ,
"value" : ""
} ,
{
"name" : "Name (optional)" ,
"type" : "string" ,
"value" : ""
} ,
{
"name" : "Email (optional)" ,
"type" : "string" ,
"value" : ""
}
] ;
}
/ * *
* @ param { string } input
* @ param { Object [ ] } args
* @ returns { string }
* /
2019-10-07 18:41:51 +02:00
async run ( input , args ) {
2021-02-01 12:10:04 +01:00
let [ keyType , keySize ] = args [ 0 ] . split ( "-" ) ;
const password = args [ 1 ] ,
2018-05-15 11:15:31 +02:00
name = args [ 2 ] ,
email = args [ 3 ] ;
let userIdentifier = "" ;
2021-02-01 12:10:04 +01:00
keyType = keyType . toLowerCase ( ) ;
keySize = parseInt ( keySize , 10 ) ;
2018-05-15 11:15:31 +02:00
if ( name ) userIdentifier += name ;
if ( email ) userIdentifier += ` < ${ email } > ` ;
let flags = kbpgp . const . openpgp . certify _keys ;
flags |= kbpgp . const . openpgp . sign _data ;
flags |= kbpgp . const . openpgp . auth ;
flags |= kbpgp . const . openpgp . encrypt _comm ;
flags |= kbpgp . const . openpgp . encrypt _storage ;
const keyGenerationOptions = {
userid : userIdentifier ,
ecc : keyType === "ecc" ,
primary : {
"nbits" : keySize ,
"flags" : flags ,
"expire_in" : 0
} ,
subkeys : [ {
"nbits" : getSubkeySize ( keySize ) ,
"flags" : kbpgp . const . openpgp . sign _data ,
"expire_in" : 86400 * 365 * 8
} , {
"nbits" : getSubkeySize ( keySize ) ,
"flags" : kbpgp . const . openpgp . encrypt _comm | kbpgp . const . openpgp . encrypt _storage ,
"expire_in" : 86400 * 365 * 2
} ] ,
asp : ASP
} ;
return new Promise ( async ( resolve , reject ) => {
try {
const unsignedKey = await promisify ( kbpgp . KeyManager . generate ) ( keyGenerationOptions ) ;
await promisify ( unsignedKey . sign . bind ( unsignedKey ) ) ( { } ) ;
const signedKey = unsignedKey ,
privateKeyExportOptions = { } ;
if ( password ) privateKeyExportOptions . passphrase = password ;
const privateKey = await promisify ( signedKey . export _pgp _private . bind ( signedKey ) ) ( privateKeyExportOptions ) ;
const publicKey = await promisify ( signedKey . export _pgp _public . bind ( signedKey ) ) ( { } ) ;
resolve ( privateKey + "\n" + publicKey . trim ( ) ) ;
} catch ( err ) {
reject ( ` Error whilst generating key pair: ${ err } ` ) ;
}
} ) ;
}
}
export default GeneratePGPKeyPair ;