161 lines
4.5 KiB
JavaScript
161 lines
4.5 KiB
JavaScript
var forge = require('../js/forge');
|
|
|
|
try {
|
|
// generate a keypair
|
|
console.log('Generating 1024-bit key-pair...');
|
|
var keys = forge.pki.rsa.generateKeyPair(1024);
|
|
console.log('Key-pair created.');
|
|
|
|
// create a certificate
|
|
console.log('Creating self-signed certificate...');
|
|
var cert = forge.pki.createCertificate();
|
|
cert.publicKey = keys.publicKey;
|
|
cert.serialNumber = '01';
|
|
cert.validity.notBefore = new Date();
|
|
cert.validity.notAfter = new Date();
|
|
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
|
|
var attrs = [{
|
|
name: 'commonName',
|
|
value: 'example.org'
|
|
}, {
|
|
name: 'countryName',
|
|
value: 'US'
|
|
}, {
|
|
shortName: 'ST',
|
|
value: 'Virginia'
|
|
}, {
|
|
name: 'localityName',
|
|
value: 'Blacksburg'
|
|
}, {
|
|
name: 'organizationName',
|
|
value: 'Test'
|
|
}, {
|
|
shortName: 'OU',
|
|
value: 'Test'
|
|
}];
|
|
cert.setSubject(attrs);
|
|
cert.setIssuer(attrs);
|
|
cert.setExtensions([{
|
|
name: 'basicConstraints',
|
|
cA: true
|
|
}, {
|
|
name: 'keyUsage',
|
|
keyCertSign: true,
|
|
digitalSignature: true,
|
|
nonRepudiation: true,
|
|
keyEncipherment: true,
|
|
dataEncipherment: true
|
|
}, {
|
|
name: 'subjectAltName',
|
|
altNames: [{
|
|
type: 6, // URI
|
|
value: 'http://example.org/webid#me'
|
|
}]
|
|
}]);
|
|
|
|
// self-sign certificate
|
|
cert.sign(keys.privateKey);
|
|
console.log('Certificate created.');
|
|
|
|
// create PKCS12
|
|
console.log('\nCreating PKCS#12...');
|
|
var password = 'password';
|
|
var newPkcs12Asn1 = forge.pkcs12.toPkcs12Asn1(
|
|
keys.privateKey, [cert], password,
|
|
{generateLocalKeyId: true, friendlyName: 'test'});
|
|
var newPkcs12Der = forge.asn1.toDer(newPkcs12Asn1).getBytes();
|
|
|
|
console.log('\nBase64-encoded new PKCS#12:');
|
|
console.log(forge.util.encode64(newPkcs12Der));
|
|
|
|
// create CA store (w/own certificate in this example)
|
|
var caStore = forge.pki.createCaStore([cert]);
|
|
|
|
console.log('\nLoading new PKCS#12 to confirm...');
|
|
loadPkcs12(newPkcs12Der, password, caStore);
|
|
} catch(ex) {
|
|
if(ex.stack) {
|
|
console.log(ex.stack);
|
|
} else {
|
|
console.log('Error', ex);
|
|
}
|
|
}
|
|
|
|
function loadPkcs12(pkcs12Der, password, caStore) {
|
|
var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);
|
|
var pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);
|
|
|
|
// load keypair and cert chain from safe content(s) and map to key ID
|
|
var map = {};
|
|
for(var sci = 0; sci < pkcs12.safeContents.length; ++sci) {
|
|
var safeContents = pkcs12.safeContents[sci];
|
|
console.log('safeContents ' + (sci + 1));
|
|
|
|
for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) {
|
|
var safeBag = safeContents.safeBags[sbi];
|
|
console.log('safeBag.type: ' + safeBag.type);
|
|
|
|
var localKeyId = null;
|
|
if(safeBag.attributes.localKeyId) {
|
|
localKeyId = forge.util.bytesToHex(
|
|
safeBag.attributes.localKeyId[0]);
|
|
console.log('localKeyId: ' + localKeyId);
|
|
if(!(localKeyId in map)) {
|
|
map[localKeyId] = {
|
|
privateKey: null,
|
|
certChain: []
|
|
};
|
|
}
|
|
} else {
|
|
// no local key ID, skip bag
|
|
continue;
|
|
}
|
|
|
|
// this bag has a private key
|
|
if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) {
|
|
console.log('found private key');
|
|
map[localKeyId].privateKey = safeBag.key;
|
|
} else if(safeBag.type === forge.pki.oids.certBag) {
|
|
// this bag has a certificate
|
|
console.log('found certificate');
|
|
map[localKeyId].certChain.push(safeBag.cert);
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log('\nPKCS#12 Info:');
|
|
|
|
for(var localKeyId in map) {
|
|
var entry = map[localKeyId];
|
|
console.log('\nLocal Key ID: ' + localKeyId);
|
|
if(entry.privateKey) {
|
|
var privateKeyP12Pem = forge.pki.privateKeyToPem(entry.privateKey);
|
|
var encryptedPrivateKeyP12Pem = forge.pki.encryptRsaPrivateKey(
|
|
entry.privateKey, password);
|
|
|
|
console.log('\nPrivate Key:');
|
|
console.log(privateKeyP12Pem);
|
|
console.log('Encrypted Private Key (password: "' + password + '"):');
|
|
console.log(encryptedPrivateKeyP12Pem);
|
|
} else {
|
|
console.log('');
|
|
}
|
|
if(entry.certChain.length > 0) {
|
|
console.log('Certificate chain:');
|
|
var certChain = entry.certChain;
|
|
for(var i = 0; i < certChain.length; ++i) {
|
|
var certP12Pem = forge.pki.certificateToPem(certChain[i]);
|
|
console.log(certP12Pem);
|
|
}
|
|
|
|
var chainVerified = false;
|
|
try {
|
|
chainVerified = forge.pki.verifyCertificateChain(caStore, certChain);
|
|
} catch(ex) {
|
|
chainVerified = ex;
|
|
}
|
|
console.log('Certificate chain verified: ', chainVerified);
|
|
}
|
|
}
|
|
}
|