invoke node-forge to generator certs

This commit is contained in:
OttoMao 2016-05-02 00:18:35 +08:00
parent 424be80b8e
commit e0ecd528cb
7 changed files with 146 additions and 147 deletions

View File

@ -1,48 +0,0 @@
#!/bin/bash
#Required
domain=$1
outputPath=$2
commonname=$domain
#Change to your company details
country=ZH
state=Shanghai
locality=Shanghai
organization=a.com
organizationalunit=IT
email=a@b.com
#Optional
password=a
if [ -z "$domain" ]
then
echo "Argument not present."
echo "Useage $0 [domain] [outputPath]"
exit 99
fi
echo "Generating key request for $outputPath$domain"
#Generate a key
# openssl genrsa -out host.key 2048
# openssl genrsa -des3 -out $outputPath$domain.key 2048 -noout
openssl genrsa -passout pass:$password -out $outputPath$domain.key 2048
#Remove passphrase from the key. Comment the line out to keep the passphrase
echo "Removing passphrase from key"
openssl rsa -in $outputPath$domain.key -passin pass:$password -out $outputPath$domain.key
#Create the request
echo "Creating CSR"
openssl req -sha256 -new -key $outputPath$domain.key -out $outputPath$domain.csr -passin pass:$password \
-subj "/C=$country/ST=$state/L=$locality/O=$organization/OU=$organizationalunit/CN=$commonname/emailAddress=$email"
#Generating a Self-Signed Certificate
openssl x509 -req -sha256 -days 3650 -in $outputPath$domain.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out $outputPath$domain.crt
# -signkey $outputPath$domain.key
#openssl x509 -req -in host.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out host.crt -days 365
echo "Finished"

View File

@ -1,27 +0,0 @@
@echo off
set domain=%1
set outputPath=%2
set commonname=%domain%
set country=ZH
set state=Shanghai
set locality=Shanghai
set organization=a.com
set organizationalunit=IT
set email=a@b.com
set password=a
echo Generating key request for %domain%
openssl genrsa -passout pass:%password% -out %domain%.key 2048
echo Removing passphrase from key
openssl rsa -in %domain%.key -passin pass:%password% -out %domain%.key
echo Creating CSR
openssl req -sha256 -new -key %domain%.key -out %domain%.csr -passin pass:%password% -subj /C=%country%/ST=%state%/L=%locality%/O=%organization%/OU=%organizationalunit%/CN=%commonname%/emailAddress=%email%
openssl x509 -req -sha256 -days 3650 -in %domain%.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out %domain%.crt
echo Finished

View File

@ -1,17 +0,0 @@
#!/bin/bash
outputPath=$1
cd $outputPath
openssl genrsa -out rootCA.key 2048
openssl req -sha256 -x509 -new -nodes -key rootCA.key -days 36500 -out rootCA.crt \
-subj "/C=CN/ST=SH/L=SH/O=AnyProxy/OU=Section/CN=Anyproxy SSL Proxying/emailAddress=AnyProxy@AnyProxy"
echo "============="
echo "rootCA generated at :"
pwd
echo "============="
chmod 666 rootCA.*
open .
exit 0

View File

@ -1,12 +0,0 @@
@echo off
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -days 3650 -out rootCA.crt -subj "/C=CN/ST=SH/L=SH/O=AnyProxy/OU=Section/CN=Anyproxy SSL Proxying/emailAddress=AnyProxy@AnyProxy"
echo =============
echo rootCA generated at :
echo %cd%
echo =============
start .
rem exit 0

85
lib/certGenerator.js Normal file
View File

@ -0,0 +1,85 @@
var forge = require('node-forge');
var defaultAttrs = [
{ name: 'countryName', value: 'CN' },
{ name: 'organizationName', value: 'AnyProxy' },
{ shortName: 'ST', value: 'SH' },
{ shortName: 'OU', value: 'AnyProxy SSL Proxy'}
];
function getKeysAndCert(){
var keys = forge.pki.rsa.generateKeyPair(1024);
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() + 10); // 10 years
return {
keys: keys,
cert: cert
};
}
function generateRootCA(){
var keysAndCert = getKeysAndCert();
keys = keysAndCert.keys;
cert = keysAndCert.cert;
var attrs = defaultAttrs.concat([
{
name: 'commonName',
value: 'AnyProxy'
}
]);
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: '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: 6, /* URI */ value: 'http://example.org/webid#me' }, { type: 7, /* IP */ ip: '127.0.0.1' } ] },
{ name: 'subjectKeyIdentifier' }
]);
cert.sign(keys.privateKey, forge.md.sha256.create());
return {
privateKey: forge.pki.privateKeyToPem(keys.privateKey),
publicKey: forge.pki.publicKeyToPem(keys.publicKey),
certificate: forge.pki.certificateToPem(cert)
};
return pem;
}
function generateCertsForHostname(domain, rootCAConfig){
var keysAndCert = getKeysAndCert();
keys = keysAndCert.keys;
cert = keysAndCert.cert;
var caCert = forge.pki.certificateFromPem(rootCAConfig.cert)
var caKey = forge.pki.privateKeyFromPem(rootCAConfig.key)
// issuer from CA
cert.setIssuer(caCert.subject.attributes)
var attrs = defaultAttrs.concat([
{
name: 'commonName',
value: domain
}
]);
cert.setSubject(attrs);
cert.sign(caKey, forge.md.sha256.create());
return {
privateKey: forge.pki.privateKeyToPem(keys.privateKey),
publicKey: forge.pki.publicKeyToPem(keys.publicKey),
certificate: forge.pki.certificateToPem(cert)
};
}
module.exports.generateRootCA = generateRootCA;
module.exports.generateCertsForHostname = generateCertsForHostname;

View File

@ -7,13 +7,13 @@ var exec = require('child_process').exec,
readline = require('readline'),
util = require('./util'),
logUtil = require("./log"),
certGenerator = require("./certGenerator"),
asyncTask = require("async-task-mgr");
var isWin = /^win/.test(process.platform);
var isWin = /^win/.test(process.platform),
certDir = path.join(util.getUserHome(),"/.anyproxy_certs/"),
cmdDir = path.join(__dirname,"..","./cert/"),
cmd_genRoot = isWin ? path.join(cmdDir,"./gen-rootCA.cmd") : path.join(cmdDir,"./gen-rootCA"),
cmd_genCert = isWin ? path.join(cmdDir,"./gen-cer.cmd") : path.join(cmdDir,"./gen-cer"),
rootCAcrtFilePath = path.join(certDir,"rootCA.crt"),
rootCAkeyFilePath = path.join(certDir,"rootCA.key"),
createCertTaskMgr = new asyncTask();
if(!fs.existsSync(certDir)){
@ -27,20 +27,31 @@ if(!fs.existsSync(certDir)){
}
}
var cache_rootCACrtFileContent, cache_rootCAKeyFileContent;
function getCertificate(hostname,certCallback){
checkRootCA();
var keyFile = path.join(certDir , "__hostname.key".replace(/__hostname/,hostname) ),
crtFile = path.join(certDir , "__hostname.crt".replace(/__hostname/,hostname) );
if(!cache_rootCACrtFileContent || !cache_rootCAKeyFileContent){
cache_rootCACrtFileContent = fs.readFileSync(rootCAcrtFilePath, {encoding: 'utf8'});
cache_rootCAKeyFileContent = fs.readFileSync(rootCAkeyFilePath, {encoding: 'utf8'});
}
createCertTaskMgr.addTask(hostname,function(callback){
if(!fs.existsSync(keyFile) || !fs.existsSync(crtFile)){
createCert(hostname,function(err){
if(err){
callback(err);
}else{
callback(null , fs.readFileSync(keyFile) , fs.readFileSync(crtFile));
}
try{
var result = certGenerator.generateCertsForHostname(hostname, {
cert: cache_rootCACrtFileContent,
key: cache_rootCAKeyFileContent
});
fs.writeFileSync(keyFile, result.privateKey);
fs.writeFileSync(crtFile, result.certificate);
callback(null, result.privateKey, result.certificate);
}catch(e){
callback(e);
}
}else{
callback(null , fs.readFileSync(keyFile) , fs.readFileSync(crtFile));
}
@ -73,19 +84,17 @@ function clearCerts(cb){
if(isWin){
exec("del * /q",{cwd : certDir},cb);
}else{
exec("rm *.key *.csr *.crt",{cwd : certDir},cb);
exec("rm *.key *.csr *.crt *.srl",{cwd : certDir},cb);
}
}
function isRootCAFileExists(){
var crtFile = path.join(certDir,"rootCA.crt"),
keyFile = path.join(certDir,"rootCA.key");
return (fs.existsSync(crtFile) && fs.existsSync(keyFile));
return (fs.existsSync(rootCAcrtFilePath) && fs.existsSync(rootCAkeyFilePath));
}
var rootCAExists = false;
function checkRootCA(){
if(rootCAExists) return;
if(!isRootCAFileExists()){
logUtil.printLog(color.red("can not find rootCA.crt or rootCA.key"), logUtil.T_ERR);
logUtil.printLog(color.red("you may generate one by the following methods"), logUtil.T_ERR);
@ -93,10 +102,13 @@ function checkRootCA(){
logUtil.printLog(color.red("\twhen using as a module : require(\"anyproxy\").generateRootCA();"), logUtil.T_ERR);
logUtil.printLog(color.red("\tmore info : https://github.com/alibaba/anyproxy/wiki/How-to-config-https-proxy"), logUtil.T_ERR);
process.exit(0);
} else{
rootCAExists = true;
}
}
function generateRootCA(){
if(isRootCAFileExists()){
logUtil.printLog(color.yellow("rootCA exists at " + certDir));
var rl = readline.createInterface({
@ -122,29 +134,33 @@ function generateRootCA(){
//clear old certs
clearCerts(function(){
logUtil.printLog(color.green("temp certs cleared"));
try{
var result = certGenerator.generateRootCA();
fs.writeFileSync(rootCAkeyFilePath, result.privateKey);
fs.writeFileSync(rootCAcrtFilePath, result.certificate);
var spawnSteam = spawn(cmd_genRoot,['.'],{cwd:certDir,stdio: 'inherit'});
spawnSteam.on('close', function (code) {
if(code == 0){
logUtil.printLog(color.green("rootCA generated"));
logUtil.printLog(color.green(color.bold("please trust the rootCA.crt in " + certDir)));
logUtil.printLog(color.green(color.bold("or you may get it via anyproxy webinterface")));
if(isWin){
exec("start .",{cwd : certDir});
}else{
exec("open .",{cwd : certDir});
}
}catch(e){
logUtil.printLog(color.red(e));
logUtil.printLog(color.red(e.stack));
logUtil.printLog(color.red("fail to generate root CA"),logUtil.T_ERR);
}
process.exit(0);
});
});
}
}
function getRootCAFilePath(){
if(isRootCAFileExists()){
return path.join(certDir,"rootCA.crt");
return rootCAcrtFilePath;
}else{
return "";
}

View File

@ -3,6 +3,7 @@ var getPort = require('./getPort'),
async = require("async"),
http = require('http'),
https = require('https'),
Buffer = require('buffer').Buffer,
fs = require('fs'),
net = require('net'),
tls = require('tls'),
@ -48,6 +49,7 @@ function SNIPrepareCert(serverName,SNICallback){
SNICallback(null,ctx);
}else{
logUtil.printLog("err occurred when prepare certs for SNI - " + err, logUtil.T_ERR);
logUtil.printLog("err occurred when prepare certs for SNI - " + err.stack, logUtil.T_ERR);
logUtil.printLog("you may upgrade your Node.js to >= v0.12", logUtil.T_ERR);
}
});