Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit 17635eb

Browse files
committed
FAB-1453 Use Identity class in User.js
the new Identity class abstracts out the management of certificates and signature verification capabilities, as well as relationship to MSP implementations. The User class needs to use the Identity class to manage serialization (to send certificates to peers along with signatures) and signature verification The following tests can successfully run with the latest fabric: - endorser-tests.js - end-to-end.js (step1, step2) Change-Id: Ida531d565f985937aeca736832bc33ab29ca475d Signed-off-by: Jim Zhang <jzhang@us.ibm.com>
1 parent 669acce commit 17635eb

File tree

8 files changed

+160
-168
lines changed

8 files changed

+160
-168
lines changed

hfc-cop/lib/FabricCOPImpl.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ var FabricCOPServices = class {
7878
* @param req Enrollment request
7979
* @param {string} req.enrollmentID The registered ID to use for enrollment
8080
* @param {string} req.enrollmentSecret The secret associated with the enrollment ID
81-
* @returns Promise for [Enrollment]{@link module:api.Enrollment}
81+
* @returns Promise for an object with "key" for private key and "certificate" for the signed certificate
8282
*/
8383
enroll(req) {
8484
var self = this;
@@ -107,7 +107,10 @@ var FabricCOPServices = class {
107107
self._fabricCOPClient.enroll(req.enrollmentID, req.enrollmentSecret, csr)
108108
.then(
109109
function (csrPEM) {
110-
return resolve(new api.Enrollment(privateKey, csrPEM));
110+
return resolve({
111+
key: privateKey,
112+
certificate: csrPEM
113+
});
111114
},
112115
function (err) {
113116
return reject(err);

hfc/lib/Chain.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,9 @@ var Chain = class {
372372
return self._clientContext.getUserContext()
373373
.then(
374374
function(userContext) {
375-
header = Chain._buildHeader(userContext.getEnrollment().certificate, request.chainId, 'lccc', request.txId, request.nonce);
375+
header = Chain._buildHeader(userContext.getIdentity(), request.chainId, 'lccc', request.txId, request.nonce);
376376
proposal = self._buildProposal(lcccSpec, header);
377-
let signed_proposal = self._signProposal(userContext.getEnrollment(), proposal);
377+
let signed_proposal = self._signProposal(userContext.getSigningIdentity(), proposal);
378378

379379
return Chain._sendPeersProposal(request.targets, signed_proposal);
380380
}
@@ -452,9 +452,9 @@ var Chain = class {
452452
return this._clientContext.getUserContext()
453453
.then(
454454
function(userContext) {
455-
header = Chain._buildHeader(userContext.getEnrollment().certificate, request.chainId, request.chaincodeId, request.txId, request.nonce);
455+
header = Chain._buildHeader(userContext.getIdentity(), request.chainId, request.chaincodeId, request.txId, request.nonce);
456456
proposal = self._buildProposal(invokeSpec, header);
457-
let signed_proposal = self._signProposal(userContext.getEnrollment(), proposal);
457+
let signed_proposal = self._signProposal(userContext.getSigningIdentity(), proposal);
458458

459459
return Chain._sendPeersProposal(request.targets, signed_proposal);
460460
}
@@ -567,7 +567,7 @@ var Chain = class {
567567
return this._clientContext.getUserContext()
568568
.then(
569569
function(userContext) {
570-
let sig = self.cryptoPrimitives.sign(userContext.getEnrollment().privateKey, payload_bytes);
570+
let sig = self.cryptoPrimitives.sign(userContext.getSigningIdentity().key, payload_bytes);
571571
let signature = Buffer.from(sig.toDER());
572572

573573
// building manually or will get protobuf errors on send
@@ -645,7 +645,7 @@ var Chain = class {
645645

646646
let signatureHeader = new _commonProto.SignatureHeader();
647647

648-
signatureHeader.setCreator(Buffer.from(creator));
648+
signatureHeader.setCreator(creator.serialize());
649649
signatureHeader.setNonce(nonce);
650650

651651
let header = new _commonProto.Header();
@@ -725,10 +725,10 @@ var Chain = class {
725725
/**
726726
* @private
727727
*/
728-
_signProposal(enrollment, proposal) {
728+
_signProposal(signingIdentity, proposal) {
729729
let proposal_bytes = proposal.toBuffer();
730730
// sign the proposal
731-
let sig = this.cryptoPrimitives.sign(enrollment.privateKey, proposal_bytes);
731+
let sig = this.cryptoPrimitives.sign(signingIdentity.key, proposal_bytes);
732732
let signature = Buffer.from(sig.toDER());
733733

734734
logger.debug('_signProposal - signature::'+JSON.stringify(signature));

hfc/lib/User.js

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818

1919
var util = require('util');
2020
var sdkUtils = require('./utils.js');
21+
var api = require('./api.js');
2122
var logger = sdkUtils.getLogger('Client.js');
23+
var Identity = require('./msp/identity.js');
24+
var MSP = require('./msp/msp.js');
2225

2326
/**
2427
* The User class represents users that have been enrolled and represented by
@@ -59,10 +62,20 @@ var User = class {
5962
}
6063

6164
this._enrollmentSecret = '';
62-
this._enrollment = null;
65+
this._identity = null;
66+
this._signingIdentity = null;
6367

6468
this._client = client;
6569
this.cryptoPrimitives = sdkUtils.getCryptoSuite();
70+
71+
// TODO: this should be using config properties obtained from the environment
72+
this.mspImpl = new MSP({
73+
trustedCerts: [],
74+
signer: 'blah',
75+
admins: [],
76+
id: 'DEFAULT',
77+
cryptoSuite: this.cryptoPrimitives
78+
});
6679
}
6780

6881
/**
@@ -106,27 +119,43 @@ var User = class {
106119
}
107120

108121
/**
109-
* Get the enrollment object for this User instance
110-
* @returns {Enrollment} the enrollment object
122+
* Get the {@link Identity} object for this User instance, used to verify signatures
123+
* @returns {Identity} the identity object that encapsulates the user's enrollment certificate
124+
*/
125+
getIdentity() {
126+
return this._identity;
127+
}
128+
129+
/**
130+
* Get the {@link SigningIdentity} object for this User instance, used to generate signatures
131+
* @returns {SigningIdentity} the identity object that encapsulates the user's private key for signing
111132
*/
112-
getEnrollment() {
113-
return this._enrollment;
133+
getSigningIdentity() {
134+
return this._signingIdentity;
114135
}
115136

116137
/**
117138
* Set the enrollment object for this User instance
118-
* @param {Enrollment} the enrollment object
139+
* @param {Key} privateKey the private key object
140+
* @param {string} certificate the PEM-encoded string of certificate
119141
*/
120-
setEnrollment(enrollment) {
121-
if (typeof enrollment.privateKey === 'undefined' || enrollment.privateKey === null || enrollment.privateKey === '') {
122-
throw new Error('Invalid enrollment object. Must have a valid private key.');
142+
setEnrollment(privateKey, certificate) {
143+
if (typeof privateKey === 'undefined' || privateKey === null || privateKey === '') {
144+
throw new Error('Invalid parameter. Must have a valid private key.');
123145
}
124146

125-
if (typeof enrollment.certificate === 'undefined' || enrollment.certificate === null || enrollment.certificate === '') {
126-
throw new Error('Invalid enrollment object. Must have a valid certificate.');
147+
if (typeof certificate === 'undefined' || certificate === null || certificate === '') {
148+
throw new Error('Invalid parameter. Must have a valid certificate.');
127149
}
128150

129-
this._enrollment = enrollment;
151+
var pubKey = this.cryptoPrimitives.importKey(certificate, { algorithm: api.CryptoAlgorithms.X509Certificate });
152+
var identity = new Identity('testIdentity', certificate, pubKey, this.mspImpl);
153+
this._identity = identity;
154+
155+
// TODO: to be encapsulated by a new class SigningIdentity
156+
this._signingIdentity = {
157+
key: privateKey
158+
};
130159
}
131160

132161
/**
@@ -155,7 +184,7 @@ var User = class {
155184
* @returns {boolean} True if enrolled; otherwise, false.
156185
*/
157186
isEnrolled() {
158-
return this._enrollment !== null;
187+
return this._identity !== null && this._signingIdentity != null;
159188
}
160189

161190
/**
@@ -174,15 +203,21 @@ var User = class {
174203
this._roles = state.roles;
175204
this._affiliation = state.affiliation;
176205
this._enrollmentSecret = state.enrollmentSecret;
177-
this._enrollment = state.enrollment;
178206

179207
var self = this;
180208

209+
var pubKey = this.cryptoPrimitives.importKey(state.enrollment.identity.certificate, { algorithm: api.CryptoAlgorithms.X509Certificate });
210+
var identity = new Identity(state.enrollment.identity.id, state.enrollment.identity.certificate, pubKey, this.mspImpl);
211+
this._identity = identity;
212+
181213
// during serialization (see toString() below) only the key's SKI are saved
182214
// swap out that for the real key from the crypto provider
183-
var promise = this.cryptoPrimitives.getKey(this._enrollment.privateKey)
184-
.then(function(key) {
185-
self._enrollment.privateKey = key;
215+
var promise = this.cryptoPrimitives.getKey(state.enrollment.signingIdentity)
216+
.then(function(privateKey) {
217+
self._signingIdentity = {
218+
key: privateKey
219+
};
220+
186221
return self;
187222
});
188223

@@ -194,9 +229,16 @@ var User = class {
194229
* @return {string} The state of this member as a string
195230
*/
196231
toString() {
197-
var serializedEnrollment = (this._enrollment) ? Object.assign({}, this._enrollment) : null;
198-
if (this._enrollment && this._enrollment.privateKey) {
199-
serializedEnrollment.privateKey = this._enrollment.privateKey.getSKI();
232+
var serializedEnrollment = {};
233+
if (this._signingIdentity) {
234+
serializedEnrollment.signingIdentity = this._signingIdentity.key.getSKI();
235+
}
236+
237+
if (this._identity) {
238+
serializedEnrollment.identity = {
239+
id: this._identity.getId(),
240+
certificate: this._identity._certificate
241+
};
200242
}
201243

202244
var state = {

hfc/lib/api.js

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -272,77 +272,3 @@ module.exports.CryptoAlgorithms = {
272272
// X509Certificate Label for X509 certificate related operation
273273
X509Certificate: 'X509Certificate'
274274
};
275-
276-
/**
277-
* Represents enrollment data for a user.
278-
*
279-
* @class
280-
*/
281-
module.exports.Enrollment = class {
282-
283-
constructor(key, cert) {
284-
/**
285-
* @member {Key} privateKey private key generated locally by the SDK
286-
* @memberof module:api.Enrollment.prototype
287-
*/
288-
this.privateKey = key;
289-
290-
/**
291-
* @member {string} certificate HEX encoded string for the certificate issued by member services after successful enrollment
292-
* @memberof module:api.Enrollment.prototype
293-
*/
294-
this.certificate = cert;
295-
}
296-
};
297-
298-
/**
299-
* The base Certificate class
300-
*
301-
* @class
302-
*/
303-
module.exports.Certificate = class {
304-
305-
constructor(cert, privateKey) {
306-
/**
307-
* @member {buffer} cert The certificate
308-
* @memberof module:api.Certificate
309-
*/
310-
this._cert = cert;
311-
312-
/**
313-
* @member {buffer} privateKey The private key
314-
* @memberof module:api.Certificate
315-
*/
316-
this._privateKey = privateKey;
317-
}
318-
319-
encode() {
320-
return this._cert;
321-
}
322-
};
323-
324-
/**
325-
* Enrollment certificate. These certificates are nominal.
326-
*
327-
* @class
328-
*/
329-
module.exports.ECert = class extends module.exports.Certificate {
330-
331-
constructor(cert, privateKey) {
332-
super(cert, privateKey);
333-
}
334-
335-
};
336-
337-
/**
338-
* Transaction certificate. These certificates are anonymous.
339-
*
340-
* @class
341-
*/
342-
module.exports.TCert = class extends module.exports.Certificate {
343-
344-
constructor(publicKey, privateKey) {
345-
super(publicKey, privateKey);
346-
}
347-
};
348-

0 commit comments

Comments
 (0)