Skip to content

Commit

Permalink
node-SDK FAB-2637 assign PKCS11 libpath based on search
Browse files Browse the repository at this point in the history
1.Change  PKCS11 libpath assignment algorithm to
  search among common paths for the softHSM2 installation.
2.Change hard coded user pin to be consistent with existing
  successful CI pkcs11 tests.
3.Add tracing to fabric-sdk-node/fabric-client/lib/impl/bccsp_pkcs11.js
4.Change fabric-sdk-node/build/tasks/test.js to
  include pkcs11.js in test-headless task.

This will cause CI to execute pkcs11.js.  The tracing will help us debug
problems.  It can be removed later.

Change-Id: I0fa094142a1aadb3315ff23f45ba70b3de2f36d5
Signed-off-by: jjjjibm <jcwolf@us.ibm.com>
Signed-off-by: Jim Zhang <jzhang@us.ibm.com>
  • Loading branch information
jimthematrix committed May 22, 2017
1 parent c3b5cb9 commit 3ff53c4
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 76 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ You can build the docker images in your native host (Mac, Ubuntu, Windows, etc.)
* `test/integration/cloudant-fabricca-tests.js`
* To re-run `node test/integration/e2e.js` or `fabric-ca-services-tests.js` stop the network (ctrl-c), clean up the docker instances (`docker rm $(docker ps -aq)`) and restart the network with `docker-compose up` as described above.

### Special Tests for Hardware Security Module support (experimental) via PKCS#11 interface
The SDK has experimental support for PKCS#11 interface in order to allow applications to make use of HSM devices for key management. Unit tests for this feature are skipped by default. To run these testss:

* set environment variable "PKCS11_TESTS" to "true"
* install a software emulator of the PKCS#11 interface. The unit tests have been tried with SoftHSM2:
* install openssl 1.0.0+ or botan 1.10.0+
* download the source code from https://dist.opendnssec.org/source/softhsm-2.2.0.tar.gz
* `tar -xvf softhsm-2.2.0.tar.gz`
* `cd softhsm-2.2.0`
* `./configure --disable-gost` (would require additional libraries, turn it off unless you need gost algorithm support for the Russian market)
* `make`
* `sudo make install`
* create a token to store keys inside slot 0: `softhsm2-util --init-token --slot 0 --label "My token 1"`, you will be prompted two PINs: SO (Security Officer) PIN that can be used to re-initialize the token, and user PIN to be used by applications to access the token for generating and retrieving keys

The unit test assumes slot '0' and user PIN `98765432`. If your configuration is different, use these environment variables to pass in the values:
* PKCS11_LIB - path to the SoftHSM2 library, if not specified, the test case searches through a list of popular install locations
* PKCS11_PIN
* PKCS11_SLOT

### Contributor Check-list
The following check-list is for code contributors to make sure their changesets are compliant to the coding standards and avoid time wasted in rejected changesets:

Expand Down
25 changes: 19 additions & 6 deletions build/tasks/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var tapColorize = require('tap-colorize');
var istanbul = require('gulp-istanbul');

var fs = require('fs-extra');
var os = require('os');
var shell = require('gulp-shell');
var testConstants = require('../../test/unit/constants.js');

Expand Down Expand Up @@ -42,11 +43,10 @@ gulp.task('test', ['clean-up', 'lint', 'docker-clean', 'pre-test', 'ca'], functi
// of the tests will re-use the same key value store that has
// saved the user certificates so they can interact with the
// network
return gulp.src([
return gulp.src(shouldRunPKCS11Tests([
'test/unit/**/*.js',
'!test/unit/constants.js',
'!test/unit/util.js',
'!test/unit/pkcs11.js',
'test/integration/fabric-ca-services-tests.js',
'test/integration/client.js',
'test/integration/orderer-chain-tests.js',
Expand All @@ -66,7 +66,7 @@ gulp.task('test', ['clean-up', 'lint', 'docker-clean', 'pre-test', 'ca'], functi
'test/integration/e2e/invoke-transaction.js',
'test/integration/e2e/query.js',
'test/integration/grpc.js'
])
]))
.pipe(tape({
reporter: tapColorize()
}))
Expand All @@ -82,12 +82,11 @@ gulp.task('test-headless', ['clean-up', 'lint', 'pre-test', 'ca'], function() {
// to the "unhandledRejection" event
process.setMaxListeners(0);

return gulp.src([
return gulp.src(shouldRunPKCS11Tests([
'test/unit/**/*.js',
'!test/unit/constants.js',
'!test/unit/util.js',
'!test/unit/pkcs11.js'
])
]))
.pipe(tape({
reporter: tapColorize()
}))
Expand All @@ -96,3 +95,17 @@ gulp.task('test-headless', ['clean-up', 'lint', 'pre-test', 'ca'], function() {
'text-summary', 'cobertura']
}));
});

// currently only the x64 CI jobs are configured with SoftHSM
// disable the pkcs11.js test for s390 or other jobs
// also skip it by default and allow it to be turned on manuall
// with an environment variable so everyone don't have to
// install SoftHsm just to run unit tests
function shouldRunPKCS11Tests(tests) {
if (os.arch().match(/(x64|x86)/) === null ||
!(typeof process.env.PKCS11_TESTS === 'string' && process.env.PKCS11_TESTS.toLowerCase() == 'true')) {
tests.push('!test/unit/pkcs11.js');
}

return tests;
}
2 changes: 2 additions & 0 deletions fabric-client/lib/impl/bccsp_pkcs11.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ var CryptoSuite_PKCS11 = class extends api.CryptoSuite {
* Open pkcs11 session and login.
*/
_pkcs11OpenSession(pkcs11, pkcs11Lib, pkcs11Slot, pkcs11Pin) {
logger.debug(__func() + 'parameters are pkcs11Slot %s pkcs11Pin %s pkcs11Lib %s',
pkcs11Slot, pkcs11Pin, pkcs11Lib);
pkcs11.load(pkcs11Lib);
pkcs11.C_Initialize();

Expand Down
18 changes: 14 additions & 4 deletions test/integration/cloudant-fabricca-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ var CouchDBKeyValueStore = require('fabric-client/lib/impl/CouchDBKeyValueStore'

var couchdbUtil = require('./couchdb-util.js');

hfc.addConfigFile('test/fixtures/cloudant.json');
var keyValueStore = hfc.getConfigSetting('key-value-store');
logger.info('cloudant Key Value Store = ' + keyValueStore);

var cloudantUrl = 'https://1421acc7-6faa-491a-8e10-951e2e190684-bluemix:7179ef7a72602189243deeabe207889bde1c2fada173ae1022b5592e5a79dacc@1421acc7-6faa-491a-8e10-951e2e190684-bluemix.cloudant.com';

hfc.addConfigFile(path.join(__dirname, 'e2e', 'config.json'));
Expand All @@ -56,6 +52,20 @@ var fabricCAEndpoint = ORGS[userOrg].ca.url;
// CouchDB KeyValueStore. Then the test uses the Chain class to load the member
// from the key value store.
test('Use FabricCAServices wih a Cloudant CouchDB KeyValueStore', function(t) {
hfc.addConfigFile('test/fixtures/cloudant.json');
var keyValueStore = hfc.getConfigSetting('key-value-store');
logger.info('cloudant Key Value Store = ' + keyValueStore);

// override t.end function so it'll always clear the config settings
t.end = ((context, f) => {
return function() {
if (global && global.hfc) global.hfc.config = undefined;
require('nconf').reset();

f.apply(context, arguments);
};
})(t, t.end);

//var user = new User();
var client = new Client();

Expand Down
32 changes: 21 additions & 11 deletions test/integration/couchdb-fabricca-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,6 @@ var FabricCAServices = require('fabric-ca-client/lib/FabricCAClientImpl');

var couchdbUtil = require('./couchdb-util.js');

// Use the CouchDB specific config file
hfc.addConfigFile('test/fixtures/couchdb.json');

var keyValueStore = hfc.getConfigSetting('key-value-store');
logger.info('couchdb Key Value Store = ' + keyValueStore);

var couchdbIPAddr = hfc.getConfigSetting('couchdb-ip-addr', 'notfound');
var couchdbPort = hfc.getConfigSetting('couchdb-port', 'notfound');
var keyValStorePath = couchdbIPAddr + ':' + couchdbPort;
logger.info('couch keyValStorePath: '+keyValStorePath);

hfc.addConfigFile(path.join(__dirname, 'e2e', 'config.json'));
var ORGS = hfc.getConfigSetting('test-network');
var userOrg = 'org1';
Expand All @@ -60,6 +49,27 @@ var fabricCAEndpoint = ORGS[userOrg].ca.url;
// CouchDB KeyValueStore. Then the test uses the Client class to load the member
// from the key value store.
test('Use FabricCAServices with a CouchDB KeyValueStore', function(t) {
// Use the CouchDB specific config file
hfc.addConfigFile('test/fixtures/couchdb.json');

var keyValueStore = hfc.getConfigSetting('key-value-store');
logger.info('couchdb Key Value Store = ' + keyValueStore);

var couchdbIPAddr = hfc.getConfigSetting('couchdb-ip-addr', 'notfound');
var couchdbPort = hfc.getConfigSetting('couchdb-port', 'notfound');
var keyValStorePath = couchdbIPAddr + ':' + couchdbPort;
logger.info('couch keyValStorePath: '+keyValStorePath);

// override t.end function so it'll always clear the config settings
t.end = ((context, f) => {
return function() {
if (global && global.hfc) global.hfc.config = undefined;
require('nconf').reset();

f.apply(context, arguments);
};
})(t, t.end);

var client = new Client();

// Set the relevant configuration values
Expand Down
13 changes: 13 additions & 0 deletions test/unit/crypto-key-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

'use strict';

if (global && global.hfc) global.hfc.config = undefined;
require('nconf').reset();

var tape = require('tape');
var _test = require('tape-promise');
var test = _test(tape);
Expand Down Expand Up @@ -269,6 +272,16 @@ test('\n\n** CryptoKeyStore tests - newCryptoKeyStore tests **\n\n', function(t)
});

test('\n\n** CryptoKeyStore tests - getKey error tests **\n\n', function(t) {
// override t.end function so it'll always clear the config settings
t.end = ((context, f) => {
return function() {
if (global && global.hfc) global.hfc.config = undefined;
require('nconf').reset();

f.apply(context, arguments);
};
})(t, t.end);

var cryptoSuite = utils.newCryptoSuite();
t.throws(
() => {
Expand Down
Loading

0 comments on commit 3ff53c4

Please sign in to comment.