Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-cronin committed Sep 9, 2020
1 parent a19e334 commit 2e1e7a7
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 196 deletions.
15 changes: 5 additions & 10 deletions src/lib/keys/KeyManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import crypto from 'crypto';
import { promisify } from 'util';
import { Pool, ModuleThread } from 'threads';
import { KeyManagerWorker } from '../keys/KeyManagerWorker';
import PublicKeyInfrastructure, { TLSCredentials } from './pki/PublicKeyInfrastructure';
import PublicKeyInfrastructure from './pki/PublicKeyInfrastructure';

type KeyManagerMetadata = {
privateKeyPath: string | null;
Expand All @@ -18,8 +18,6 @@ type KeyPair = {
public: string | null;
};

type PKInfo = { key: Buffer | null; cert: Buffer | null; caCert: Buffer | null };

class KeyManager {
private primaryKeyPair: KeyPair = { private: null, public: null };
private primaryIdentity?: Object;
Expand All @@ -36,9 +34,6 @@ class KeyManager {
private metadata: KeyManagerMetadata = {
privateKeyPath: null,
publicKeyPath: null,
// pkiKeyPath: null,
// pkiCertPath: null,
// caCertPath: null,
};

/////////
Expand Down Expand Up @@ -76,14 +71,14 @@ class KeyManager {
/////////
// PKI //
/////////
let pkiVaultKey: Buffer
let pkiSymmetricKey: Buffer
if (this.hasKey('polykey_pki_vault_key')) {
pkiVaultKey = this.getKey('polykey_pki_vault_key')
pkiSymmetricKey = this.getKey('polykey_pki_vault_key')
} else {
pkiVaultKey = this.generateKeySync('polykey_pki_vault_key', 'sf', true)
pkiSymmetricKey = this.generateKeySync('polykey_pki_vault_key', 'sf', true)
}

this.pki = new PublicKeyInfrastructure(polyKeyPath, pkiVaultKey, process.env.PK_HOST ?? 'localhost')
this.pki = new PublicKeyInfrastructure(polyKeyPath, pkiSymmetricKey, process.env.PK_HOST ?? 'localhost')
}

public get identityLoaded(): boolean {
Expand Down
132 changes: 81 additions & 51 deletions src/lib/keys/pki/PublicKeyInfrastructure.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import fs from 'fs'
import path from 'path'
import { pki } from 'node-forge';
import Vault from '../../vaults/Vault';
import { EncryptedFS } from 'encryptedfs';

type TLSCredentials = { privateKey: string, certificate: string, rootCertificate: string }
/**
Expand All @@ -9,8 +11,8 @@ class PublicKeyInfrastructure {
commonName: string;

// pki vault
polykeyPath: string
pkiVault: Vault
pkiPath: string
pkiEfs: EncryptedFS

// certificate signed by another
private keypair: pki.rsa.KeyPair
Expand All @@ -25,7 +27,6 @@ class PublicKeyInfrastructure {


public get TLSClientCredentials(): TLSCredentials | undefined {
console.log(this.certificate);
if (this.certificate) {
return {
privateKey: pki.privateKeyToPem(this.keypair.privateKey),
Expand All @@ -37,7 +38,6 @@ class PublicKeyInfrastructure {


public get TLSServerCredentials(): TLSCredentials | undefined {
console.log(this.certificate);
if (this.certificate) {
return {
privateKey: pki.privateKeyToPem(this.keypair.privateKey),
Expand All @@ -62,10 +62,17 @@ class PublicKeyInfrastructure {
symmetricKey: Buffer,
commonName: string
) {
this.polykeyPath = polykeyPath
this.pkiVault = new Vault('.pkiVault', symmetricKey, polykeyPath)
// create efs instance
const vfsInstance = new (require('virtualfs').VirtualFS)();
this.pkiEfs = new EncryptedFS(
symmetricKey,
vfsInstance,
vfsInstance,
fs,
process
);
this.pkiPath = path.join(polykeyPath, '.pki')
this.commonName = commonName

this.loadMetadata()
}

Expand Down Expand Up @@ -211,21 +218,51 @@ class PublicKeyInfrastructure {

cert.setSubject(csr.subject.attributes);
cert.setIssuer(this.rootCertificate.issuer.attributes);
cert.publicKey = csr.publicKey;

cert.setExtensions([...(csr.extensions ?? []),
{
name: 'basicConstraints',
cA: false
}, {
cA: true,
},
{
name: 'keyUsage',
keyCertSign: true,
digitalSignature: true,
nonRepudiation: true,
keyEncipherment: true,
dataEncipherment: true
}
dataEncipherment: true,
},
{
name: 'extKeyUsage',
serverAuth: true,
clientAuth: true,
codeSigning: true,
emailProtection: true,
timeStamping: true,
},
{
name: 'nsCertType',
client: true,
server: true,
email: true,
objsign: true,
sslCA: true,
emailCA: true,
objCA: true,
},
{
name: 'subjectAltName',
altNames: {
type: 7, // IP
ip: '127.0.0.1',
},
},
{
name: 'subjectKeyIdentifier',
},
]);

cert.publicKey = csr.publicKey;

// self-sign certificate
cert.sign(this.keypair.privateKey);
Expand All @@ -247,36 +284,47 @@ class PublicKeyInfrastructure {

// ===== Helper methods ===== //
private loadMetadata(): void {
// load keypairs
if (this.pkiVault.secretExists('keypair')) {
this.keypair = JSON.parse(this.pkiVault.getSecret('keypair').toString())
// make the pkiPath directory
this.pkiEfs.mkdirSync(this.pkiPath, { recursive: true })

// load keypair
const keypairPath = path.join(this.pkiPath, 'keypair')
if (this.pkiEfs.existsSync(keypairPath)) {
this.keypair = JSON.parse(this.pkiEfs.readFileSync(keypairPath).toString())
} else {
// create the keypair if it doesn't exist
this.keypair = pki.rsa.generateKeyPair()
}

if (this.pkiVault.secretExists('root_keypair')) {
this.rootKeypair = JSON.parse(this.pkiVault.getSecret('root_keypair').toString())
// load root keypair
const rootKeypairPath = path.join(this.pkiPath, 'root_keypair')
if (this.pkiEfs.existsSync(rootKeypairPath)) {
this.rootKeypair = JSON.parse(this.pkiEfs.readFileSync(rootKeypairPath).toString())
} else {
// create the keys if it doesn't exist
// create the keypair if it doesn't exist
this.rootKeypair = pki.rsa.generateKeyPair()
}

// load certificates
if (this.pkiVault.secretExists('certificate')) {
this.certificate = pki.certificateFromPem(this.pkiVault.getSecret('certificate').toString())
// load certificate
const certificatePath = path.join(this.pkiPath, 'certificate')
if (this.pkiEfs.existsSync(certificatePath)) {
this.certificate = pki.certificateFromPem(this.pkiEfs.readFileSync(certificatePath).toString())
}
if (this.pkiVault.secretExists('root_certificate')) {
this.rootCertificate = pki.certificateFromPem(this.pkiVault.getSecret('root_certificate').toString())

// load root certificate
const rootCertificatePath = path.join(this.pkiPath, 'root_certificate')
if (this.pkiEfs.existsSync(rootCertificatePath)) {
this.rootCertificate = pki.certificateFromPem(this.pkiEfs.readFileSync(rootCertificatePath).toString())
} else {
// create the certificate if it doesn't exist
this.rootCertificate = this.createCACertificate()
}

// CA store
const parsedCertificates: pki.Certificate[] = []
if (this.pkiVault.secretExists('ca_store_certificates')) {
const certificates: string[] = JSON.parse(this.pkiVault.getSecret('ca_store_certificates').toString())
const caStorePath = path.join(this.pkiPath, 'ca_store_certificates')
if (this.pkiEfs.existsSync(caStorePath)) {
const certificates: string[] = JSON.parse(this.pkiEfs.readFileSync(caStorePath).toString())
parsedCertificates.push(...certificates.map((c) => pki.certificateFromPem(c)))
}
this.CAStore = pki.createCaStore(parsedCertificates)
Expand All @@ -287,36 +335,18 @@ class PublicKeyInfrastructure {

private writeMetadata(): void {
// write keypairs
if (this.pkiVault.secretExists('keypair')) {
this.pkiVault.updateSecret('keypair', Buffer.from(JSON.stringify(this.keypair)))
} else {
// add if it doesn't exist
this.pkiVault.addSecret('keypair', Buffer.from(JSON.stringify(this.keypair)))
}
if (this.pkiVault.secretExists('root_keypair')) {
this.pkiVault.updateSecret('root_keypair', Buffer.from(JSON.stringify(this.rootKeypair)))
} else {
// add if it doesn't exist
this.pkiVault.addSecret('root_keypair', Buffer.from(JSON.stringify(this.rootKeypair)))
}
this.pkiEfs.writeFileSync(path.join(this.pkiPath, 'keypair'), Buffer.from(JSON.stringify(this.keypair)))
this.pkiEfs.writeFileSync(path.join(this.pkiPath, 'root_keypair'), Buffer.from(JSON.stringify(this.rootKeypair)))

// write certificates
if (this.certificate) {
const certificate = Buffer.from(pki.certificateToPem(this.certificate))
if (this.pkiVault.secretExists('certificate')) {
this.pkiVault.updateSecret('certificate', certificate)
} else {
// add if it doesn't exist
this.pkiVault.addSecret('certificate', certificate)
}
this.pkiEfs.writeFileSync(path.join(this.pkiPath, 'certificate'), Buffer.from(pki.certificateToPem(this.certificate)))
}
this.pkiEfs.writeFileSync(path.join(this.pkiPath, 'root_certificate'), Buffer.from(pki.certificateToPem(this.rootCertificate)))

const rootCertificate = Buffer.from(pki.certificateToPem(this.rootCertificate))
if (this.pkiVault.secretExists('root_certificate')) {
this.pkiVault.updateSecret('root_certificate', rootCertificate)
} else {
this.pkiVault.addSecret('root_certificate', rootCertificate)
}
// write ca store
const certsJson = JSON.stringify(this.CAStore.listAllCertificates().map((c) => pki.certificateToPem(c)))
this.pkiEfs.writeFileSync(path.join(this.pkiPath, 'ca_store_certificates'), certsJson)
}
}

Expand Down
44 changes: 44 additions & 0 deletions src/lib/vaults/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,42 @@ class Vault {
this.loadMetadata();
}

async initializeVault(): Promise<void> {
// Init repository for vault
const efs = this.EncryptedFS;
const fileSystem = { promises: efs.promises };
// first make sure its not already initialized
try {
const statusMatrix = await git.statusMatrix({
fs: fileSystem,
dir:this.vaultPath
})
if (statusMatrix == undefined) {
return
}
} catch (error) {
return
}

await git.init({
fs: fileSystem,
dir: this.vaultPath,
});

// Initial commit
await git.commit({
fs: fileSystem,
dir: this.vaultPath,
author: {
name: this.name,
},
message: 'init commit',
});
// Write packed-refs file because isomorphic git goes searching for it
// and apparently its not autogenerated
efs.writeFileSync(Path.join(this.vaultPath, '.git', 'packed-refs'), '# pack-refs with: peeled fully-peeled sorted');
}

/**
* Returns the Encrypted File System used for vault operations
*/
Expand Down Expand Up @@ -72,13 +108,21 @@ class Vault {
}
const writePath = Path.join(this.vaultPath, secretName);
// Write secret
console.log(writePath);

await this.efs.promises.writeFile(writePath, secret, {});
// Update secrets map
this.secrets.set(secretName, secret);
console.log('heyyyyy');

// Auto commit message
await this.commitChanges(`Add secret: ${secretName}`, secretName, 'added');
} catch (error) {
release();
console.log('skdksndfkjsdnfksjdnf');
console.log(error);


throw error;
} finally {
release();
Expand Down
23 changes: 1 addition & 22 deletions src/lib/vaults/VaultManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,7 @@ class VaultManager {

// Create vault
const vault = new Vault(vaultName, vaultKey, this.polykeyPath);

// Init repository for vault
const vaultPath = Path.join(this.polykeyPath, vaultName);
const efs = vault.EncryptedFS;
const fileSystem = { promises: efs.promises };
await git.init({
fs: fileSystem,
dir: vaultPath,
});

// Initial commit
await git.commit({
fs: fileSystem,
dir: vaultPath,
author: {
name: vaultName,
},
message: 'init commit',
});
// Write packed-refs file because isomorphic git goes searching for it
// and apparently its not autogenerated
efs.writeFileSync(Path.join(vaultPath, '.git', 'packed-refs'), '# pack-refs with: peeled fully-peeled sorted');
await vault.initializeVault()

// Set vault
this.vaults.set(vaultName, vault);
Expand Down
Loading

0 comments on commit 2e1e7a7

Please sign in to comment.