blob: e52eefa0fed3c98055582caa457a08fdce4656c9 [file] [log] [blame]
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);
}
}
}