83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
|
import * as plugins from './plugins.js';
|
||
|
|
||
|
interface DnssecZone {
|
||
|
zone: string;
|
||
|
algorithm: string;
|
||
|
keySize: number;
|
||
|
days: number;
|
||
|
}
|
||
|
|
||
|
interface DnssecKeyPair {
|
||
|
private: string;
|
||
|
public: string;
|
||
|
}
|
||
|
|
||
|
class DnsSec {
|
||
|
private zone: DnssecZone;
|
||
|
private keyPair: DnssecKeyPair;
|
||
|
private ec: any; // declare the ec instance
|
||
|
|
||
|
constructor(zone: DnssecZone) {
|
||
|
this.zone = zone;
|
||
|
this.ec = new plugins.elliptic.ec('secp256k1'); // Create an instance of the secp256k1 curve
|
||
|
this.keyPair = this.generateKeyPair();
|
||
|
}
|
||
|
|
||
|
private generateKeyPair(): DnssecKeyPair {
|
||
|
const key = this.ec.genKeyPair();
|
||
|
const privatePem = key.getPrivate().toString('hex'); // get private key in hex format
|
||
|
// @ts-ignore
|
||
|
const publicPem = key.getPublic().toString('hex'); // get public key in hex format
|
||
|
|
||
|
return {
|
||
|
private: privatePem,
|
||
|
public: publicPem
|
||
|
};
|
||
|
}
|
||
|
|
||
|
private formatPEM(pem: string, type: string): string {
|
||
|
const start = `-----BEGIN ${type}-----`;
|
||
|
const end = `-----END ${type}-----`;
|
||
|
|
||
|
const formatted = [start];
|
||
|
for (let i = 0; i < pem.length; i += 64) {
|
||
|
formatted.push(pem.slice(i, i + 64));
|
||
|
}
|
||
|
formatted.push(end);
|
||
|
return formatted.join('\n');
|
||
|
}
|
||
|
|
||
|
public getDSRecord(): string {
|
||
|
const publicPem = this.keyPair.public;
|
||
|
const publicKey = this.ec.keyFromPublic(publicPem); // Create a public key from the publicPEM
|
||
|
|
||
|
const digest = publicKey.getPublic(); // get public point
|
||
|
return `DS {id} 8 {algorithm} {digest} {hash-algorithm}\n`
|
||
|
.replace('{id}', '256') // zone hash
|
||
|
.replace('{algorithm}', this.getAlgorithm())
|
||
|
.replace('{digest}', `0x${digest.getX()}${digest.getY()}`)
|
||
|
.replace('{hash-algorithm}', '2');
|
||
|
}
|
||
|
|
||
|
private getAlgorithm(): string {
|
||
|
switch (this.zone.algorithm) {
|
||
|
case 'ECDSA':
|
||
|
return '8';
|
||
|
case 'ED25519':
|
||
|
return '15';
|
||
|
case 'RSA':
|
||
|
return '1';
|
||
|
default:
|
||
|
throw new Error(`Unsupported algorithm: ${this.zone.algorithm}`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public getKeyPair(): DnssecKeyPair {
|
||
|
return this.keyPair;
|
||
|
}
|
||
|
|
||
|
public getDsAndKeyPair(): [DnssecKeyPair, string] {
|
||
|
const dsRecord = this.getDSRecord();
|
||
|
return [this.keyPair, dsRecord];
|
||
|
}
|
||
|
}
|