@@ -24,7 +24,11 @@ import (
24
24
25
25
"bytes"
26
26
27
+ "crypto/x509/pkix"
28
+ "encoding/asn1"
27
29
"errors"
30
+ "math/big"
31
+ "reflect"
28
32
29
33
"github.com/golang/protobuf/proto"
30
34
"github.com/hyperledger/fabric/bccsp"
@@ -57,6 +61,9 @@ type bccspmsp struct {
57
61
58
62
// verification options for MSP members
59
63
opts * x509.VerifyOptions
64
+
65
+ // list of certificate revocation lists
66
+ CRL []* pkix.CertificateList
60
67
}
61
68
62
69
// NewBccspMsp returns an MSP instance backed up by a BCCSP
@@ -140,6 +147,86 @@ func (msp *bccspmsp) getSigningIdentityFromConf(sidInfo *m.SigningIdentityInfo)
140
147
idPub .(* identity ).cert , idPub .(* identity ).pk , peerSigner , msp ), nil
141
148
}
142
149
150
+ /*
151
+ This is the definition of the ASN.1 marshalling of AuthorityKeyIdentifier
152
+ from https://www.ietf.org/rfc/rfc5280.txt
153
+
154
+ AuthorityKeyIdentifier ::= SEQUENCE {
155
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
156
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
157
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
158
+
159
+ KeyIdentifier ::= OCTET STRING
160
+
161
+ CertificateSerialNumber ::= INTEGER
162
+
163
+ */
164
+
165
+ type authorityKeyIdentifier struct {
166
+ KeyIdentifier []byte `asn1:"optional,tag:0"`
167
+ AuthorityCertIssuer []byte `asn1:"optional,tag:1"`
168
+ AuthorityCertSerialNumber big.Int `asn1:"optional,tag:2"`
169
+ }
170
+
171
+ // getAuthorityKeyIdentifierFromCrl returns the Authority Key Identifier
172
+ // for the supplied CRL. The authority key identifier can be used to identify
173
+ // the public key corresponding to the private key which was used to sign the CRL.
174
+ func getAuthorityKeyIdentifierFromCrl (crl * pkix.CertificateList ) ([]byte , error ) {
175
+ aki := authorityKeyIdentifier {}
176
+
177
+ for _ , ext := range crl .TBSCertList .Extensions {
178
+ // Authority Key Identifier is identified by the following ASN.1 tag
179
+ // authorityKeyIdentifier (2 5 29 35) (see https://tools.ietf.org/html/rfc3280.html)
180
+ if reflect .DeepEqual (ext .Id , asn1.ObjectIdentifier {2 , 5 , 29 , 35 }) {
181
+ _ , err := asn1 .Unmarshal (ext .Value , & aki )
182
+ if err != nil {
183
+ return nil , fmt .Errorf ("Failed to unmarshal AKI, error %s" , err )
184
+ }
185
+
186
+ return aki .KeyIdentifier , nil
187
+ }
188
+ }
189
+
190
+ return nil , errors .New ("authorityKeyIdentifier not found in certificate" )
191
+ }
192
+
193
+ // getSubjectKeyIdentifierFromCert returns the Subject Key Identifier for the supplied certificate
194
+ // Subject Key Identifier is an identifier of the public key of this certificate
195
+ func getSubjectKeyIdentifierFromCert (cert * x509.Certificate ) ([]byte , error ) {
196
+ var SKI []byte
197
+
198
+ for _ , ext := range cert .Extensions {
199
+ // Subject Key Identifier is identified by the following ASN.1 tag
200
+ // subjectKeyIdentifier (2 5 29 14) (see https://tools.ietf.org/html/rfc3280.html)
201
+ if reflect .DeepEqual (ext .Id , asn1.ObjectIdentifier {2 , 5 , 29 , 14 }) {
202
+ _ , err := asn1 .Unmarshal (ext .Value , & SKI )
203
+ if err != nil {
204
+ return nil , fmt .Errorf ("Failed to unmarshal Subject Key Identifier, err %s" , err )
205
+ }
206
+
207
+ return SKI , nil
208
+ }
209
+ }
210
+
211
+ return nil , errors .New ("subjectKeyIdentifier not found in certificate" )
212
+ }
213
+
214
+ // isCAProperlyFormed does a few checks on the certificate,
215
+ // assuming it's a CA; it returns true if all looks good
216
+ // and false otherwise
217
+ func isCAProperlyFormed (cert * x509.Certificate ) bool {
218
+ _ , err := getSubjectKeyIdentifierFromCert (cert )
219
+ if err != nil {
220
+ return false
221
+ }
222
+
223
+ if ! cert .IsCA {
224
+ return false
225
+ }
226
+
227
+ return true
228
+ }
229
+
143
230
// Setup sets up the internal data structures
144
231
// for this MSP, given an MSPConfig ref; it
145
232
// returns nil in case of success or an error otherwise
@@ -160,16 +247,14 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
160
247
mspLogger .Debugf ("Setting up MSP instance %s" , msp .name )
161
248
162
249
// make and fill the set of admin certs (if present)
163
- if conf .Admins != nil {
164
- msp .admins = make ([]Identity , len (conf .Admins ))
165
- for i , admCert := range conf .Admins {
166
- id , err := msp .getIdentityFromConf (admCert )
167
- if err != nil {
168
- return err
169
- }
170
-
171
- msp .admins [i ] = id
250
+ msp .admins = make ([]Identity , len (conf .Admins ))
251
+ for i , admCert := range conf .Admins {
252
+ id , err := msp .getIdentityFromConf (admCert )
253
+ if err != nil {
254
+ return err
172
255
}
256
+
257
+ msp .admins [i ] = id
173
258
}
174
259
175
260
// make and fill the set of CA certs - we expect them to be there
@@ -187,18 +272,21 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
187
272
}
188
273
189
274
// make and fill the set of intermediate certs (if present)
190
- if conf .IntermediateCerts != nil {
191
- msp .intermediateCerts = make ([]Identity , len (conf .IntermediateCerts ))
192
- for i , trustedCert := range conf .IntermediateCerts {
193
- id , err := msp .getIdentityFromConf (trustedCert )
194
- if err != nil {
195
- return err
196
- }
275
+ msp .intermediateCerts = make ([]Identity , len (conf .IntermediateCerts ))
276
+ for i , trustedCert := range conf .IntermediateCerts {
277
+ id , err := msp .getIdentityFromConf (trustedCert )
278
+ if err != nil {
279
+ return err
280
+ }
197
281
198
- msp .intermediateCerts [i ] = id
282
+ msp .intermediateCerts [i ] = id
283
+ }
284
+
285
+ // ensure that our CAs are properly formed
286
+ for _ , cert := range append (append ([]Identity {}, msp .rootCerts ... ), msp .intermediateCerts ... ) {
287
+ if ! isCAProperlyFormed (cert .(* identity ).cert ) {
288
+ return fmt .Errorf ("CA Certificate did not have the Subject Key Identifier extension, (SN: %s)" , cert .(* identity ).cert .SerialNumber )
199
289
}
200
- } else {
201
- msp .intermediateCerts = make ([]Identity , 0 )
202
290
}
203
291
204
292
// setup the signer (if present)
@@ -223,6 +311,52 @@ func (msp *bccspmsp) Setup(conf1 *m.MSPConfig) error {
223
311
msp .opts .Intermediates .AddCert (v .(* identity ).cert )
224
312
}
225
313
314
+ // setup the CRL (if present)
315
+ msp .CRL = make ([]* pkix.CertificateList , len (conf .RevocationList ))
316
+ for i , crlbytes := range conf .RevocationList {
317
+ valid := false
318
+
319
+ // at first we parse it
320
+ crl , err := x509 .ParseCRL (crlbytes )
321
+ if err != nil {
322
+ return fmt .Errorf ("Could not parse RevocationList, err %s" , err )
323
+ }
324
+
325
+ // we extract the AKI - this is needed so that we know which CA should have signed us
326
+ aki , err := getAuthorityKeyIdentifierFromCrl (crl )
327
+ if err != nil {
328
+ return fmt .Errorf ("Could not get AuthorityKeyIdentifier from RevocationList, err %s" , err )
329
+ }
330
+
331
+ // now check the signature over the CRL - it has to be signed
332
+ // by one of our CAs (either root or intermediate)
333
+ for _ , ca := range append (append ([]Identity {}, msp .rootCerts ... ), msp .intermediateCerts ... ) {
334
+ // get the SKI for the CA
335
+ ski , err := getSubjectKeyIdentifierFromCert (ca .(* identity ).cert )
336
+ if err != nil {
337
+ return fmt .Errorf ("Could not get SubjectKeyIdentifier from CA cert, err %s" , err )
338
+ }
339
+
340
+ // this is the CA that should have signed
341
+ // this CRL, check its signature over it
342
+ if bytes .Equal (aki , ski ) {
343
+ err := ca .(* identity ).cert .CheckCRLSignature (crl )
344
+ if err != nil {
345
+ return fmt .Errorf ("Invalid signature on the CRL, err %s" , err )
346
+ }
347
+ valid = true
348
+ break
349
+ }
350
+ }
351
+
352
+ // valid may not be set in case none of the CAs signed the CRL
353
+ if ! valid {
354
+ return errors .New ("Could not verify signature over the CRL" )
355
+ }
356
+
357
+ msp .CRL [i ] = crl
358
+ }
359
+
226
360
return nil
227
361
}
228
362
@@ -263,7 +397,7 @@ func (msp *bccspmsp) GetSigningIdentity(identifier *IdentityIdentifier) (Signing
263
397
func (msp * bccspmsp ) Validate (id Identity ) error {
264
398
mspLogger .Infof ("MSP %s validating identity" , msp .name )
265
399
266
- switch id .(type ) {
400
+ switch id := id .(type ) {
267
401
// If this identity is of this specific type,
268
402
// this is how I can validate it given the
269
403
// root of trust this MSP has
@@ -274,7 +408,7 @@ func (msp *bccspmsp) Validate(id Identity) error {
274
408
}
275
409
276
410
// CAs cannot be directly used as identities..
277
- if id .( * identity ). cert .IsCA {
411
+ if id .cert .IsCA {
278
412
return errors .New ("A CA certificate cannot be used directly by this MSP" )
279
413
}
280
414
@@ -290,12 +424,57 @@ func (msp *bccspmsp) Validate(id Identity) error {
290
424
// signed by CA but not by CA -> iCA1)
291
425
292
426
// ask golang to validate the cert for us based on the options that we've built at setup time
293
- _ , err := id .( * identity ) .cert .Verify (* (msp .opts ))
427
+ validationChain , err := id .cert .Verify (* (msp .opts ))
294
428
if err != nil {
295
429
return fmt .Errorf ("The supplied identity is not valid, Verify() returned %s" , err )
296
- } else {
297
- return nil
298
430
}
431
+
432
+ // we only support a single validation chain;
433
+ // if there's more than one then there might
434
+ // be unclarity about who owns the identity
435
+ if len (validationChain ) != 1 {
436
+ return fmt .Errorf ("This MSP only supports a single validation chain, got %d" , len (validationChain ))
437
+ }
438
+
439
+ // we expect a chain of length at least 2
440
+ if len (validationChain [0 ]) < 2 {
441
+ return fmt .Errorf ("Expected a chain of length at least 2, got %d" , len (validationChain ))
442
+ }
443
+
444
+ // here we know that the identity is valid; now we have to check whether it has been revoked
445
+
446
+ // identify the SKI of the CA that signed this cert
447
+ SKI , err := getSubjectKeyIdentifierFromCert (validationChain [0 ][1 ])
448
+ if err != nil {
449
+ return fmt .Errorf ("Could not obtain Subject Key Identifier for signer cert, err %s" , err )
450
+ }
451
+
452
+ // check whether one of the CRLs we have has this cert's
453
+ // SKI as its AuthorityKeyIdentifier
454
+ for _ , crl := range msp .CRL {
455
+ aki , err := getAuthorityKeyIdentifierFromCrl (crl )
456
+ if err != nil {
457
+ return fmt .Errorf ("Could not obtain Authority Key Identifier for crl, err %s" , err )
458
+ }
459
+
460
+ // check if the SKI of the cert that signed us matches the AKI of any of the CRLs
461
+ if bytes .Equal (aki , SKI ) {
462
+ // we have a CRL, check whether the serial number is revoked
463
+ for _ , rc := range crl .TBSCertList .RevokedCertificates {
464
+ if rc .SerialNumber .Cmp (id .cert .SerialNumber ) == 0 {
465
+ // A CRL also includes a time of revocation so that
466
+ // the CA can say "this cert is to be revoked starting
467
+ // from this time"; however here we just assume that
468
+ // revocation applies instantaneously from the time
469
+ // the MSP config is committed and used so we will not
470
+ // make use of that field
471
+ return errors .New ("The certificate has been revoked" )
472
+ }
473
+ }
474
+ }
475
+ }
476
+
477
+ return nil
299
478
default :
300
479
return fmt .Errorf ("Identity type not recognized" )
301
480
}
0 commit comments