@@ -294,6 +294,33 @@ func computeSKI(key *ecdsa.PublicKey) []byte {
294
294
return hash [:]
295
295
}
296
296
297
+ func TestValidHostname (t * testing.T ) {
298
+ tests := []struct {
299
+ name string
300
+ valid bool
301
+ }{
302
+ {"" , false },
303
+ {"." , false },
304
+ {"example.com" , true },
305
+ {"example.com." , true },
306
+ {"*.example.com" , true },
307
+ {".example.com" , false },
308
+ {"host.*.example.com" , false },
309
+ {"localhost" , true },
310
+ {"-localhost" , false },
311
+ {"Not_Quite.example.com" , true },
312
+ {"weird:colon.example.com" , true },
313
+ {"1-2-3.example.com" , true },
314
+ }
315
+ for _ , tt := range tests {
316
+ if tt .valid {
317
+ require .True (t , validHostname (tt .name ), "expected %s to be a valid hostname" , tt .name )
318
+ } else {
319
+ require .False (t , validHostname (tt .name ), "expected %s to be an invalid hostname" , tt .name )
320
+ }
321
+ }
322
+ }
323
+
297
324
func TestValidateCANameConstraintsMitigation (t * testing.T ) {
298
325
// Prior to Go 1.15, if a signing certificate contains a name constraint, the
299
326
// leaf certificate does not include a SAN, and the leaf common name looks
@@ -320,9 +347,9 @@ func TestValidateCANameConstraintsMitigation(t *testing.T) {
320
347
KeyUsage : caKeyUsage ,
321
348
SubjectKeyId : computeSKI (caKey .Public ().(* ecdsa.PublicKey )),
322
349
}
323
- certBytes , err := x509 .CreateCertificate (rand .Reader , & caTemplate , & caTemplate , caKey .Public (), caKey )
350
+ caCertBytes , err := x509 .CreateCertificate (rand .Reader , & caTemplate , & caTemplate , caKey .Public (), caKey )
324
351
require .NoError (t , err )
325
- ca , err := x509 .ParseCertificate (certBytes )
352
+ ca , err := x509 .ParseCertificate (caCertBytes )
326
353
require .NoError (t , err )
327
354
328
355
leafTemplate := x509.Certificate {
@@ -339,37 +366,82 @@ func TestValidateCANameConstraintsMitigation(t *testing.T) {
339
366
keyBytes , err := x509 .MarshalPKCS8PrivateKey (leafKey )
340
367
require .NoError (t , err )
341
368
342
- caCertPem := pem .EncodeToMemory (& pem.Block {Type : "CERTIFICATE" , Bytes : certBytes })
369
+ caCertPem := pem .EncodeToMemory (& pem.Block {Type : "CERTIFICATE" , Bytes : caCertBytes })
343
370
leafCertPem := pem .EncodeToMemory (& pem.Block {Type : "CERTIFICATE" , Bytes : leafCertBytes })
344
371
leafKeyPem := pem .EncodeToMemory (& pem.Block {Type : "PRIVATE KEY" , Bytes : keyBytes })
345
- fabricMSPConfig := & msp.FabricMSPConfig {
346
- Name : "ConstraintsMSP" ,
347
- RootCerts : [][]byte {caCertPem },
348
- SigningIdentity : & msp.SigningIdentityInfo {
349
- PublicSigner : leafCertPem ,
350
- PrivateSigner : & msp.KeyInfo {
351
- KeyIdentifier : "Certificate Without SAN" ,
352
- KeyMaterial : leafKeyPem ,
353
- },
354
- },
355
- }
356
- mspConfig := & msp.MSPConfig {
357
- Config : protoutil .MarshalOrPanic (fabricMSPConfig ),
358
- }
359
372
360
- ks , err := sw . NewFileBasedKeyStore ( nil , filepath . Join ( configtest . GetDevMspDir (), "keystore" ), true )
361
- require . NoError ( t , err )
362
- cryptoProvider , err := sw . NewDefaultSecurityLevelWithKeystore ( ks )
363
- require .NoError (t , err )
373
+ t . Run ( "VerifyNameConstraintsSingleCert" , func ( t * testing. T ) {
374
+ for _ , der := range [][] byte { caCertBytes , leafCertBytes } {
375
+ cert , err := x509 . ParseCertificate ( der )
376
+ require .NoError (t , err , "failed to parse certificate" )
364
377
365
- testMSP , err := NewBccspMspWithKeyStore (MSPv1_0 , ks , cryptoProvider )
366
- require .NoError (t , err )
378
+ err = verifyLegacyNameConstraints ([]* x509.Certificate {cert })
379
+ require .NoError (t , err , "single certificate should not trigger legacy constraints" )
380
+ }
381
+ })
367
382
368
- err = testMSP .Setup (mspConfig )
369
- require .Error (t , err )
370
- var cie x509.CertificateInvalidError
371
- require .True (t , errors .As (err , & cie ))
372
- require .Equal (t , x509 .NameConstraintsWithoutSANs , cie .Reason )
383
+ t .Run ("VerifyNameConstraints" , func (t * testing.T ) {
384
+ var certs []* x509.Certificate
385
+ for _ , der := range [][]byte {leafCertBytes , caCertBytes } {
386
+ cert , err := x509 .ParseCertificate (der )
387
+ require .NoError (t , err , "failed to parse certificate" )
388
+ certs = append (certs , cert )
389
+ }
390
+
391
+ err = verifyLegacyNameConstraints (certs )
392
+ require .Error (t , err , "certificate chain should trigger legacy constraints" )
393
+ var cie x509.CertificateInvalidError
394
+ require .True (t , errors .As (err , & cie ))
395
+ require .Equal (t , x509 .NameConstraintsWithoutSANs , cie .Reason )
396
+ })
397
+
398
+ t .Run ("VerifyNameConstraintsWithSAN" , func (t * testing.T ) {
399
+ caCert , err := x509 .ParseCertificate (caCertBytes )
400
+ require .NoError (t , err )
401
+
402
+ leafTemplate := leafTemplate
403
+ leafTemplate .DNSNames = []string {"localhost" }
404
+
405
+ leafCertBytes , err := x509 .CreateCertificate (rand .Reader , & leafTemplate , caCert , leafKey .Public (), caKey )
406
+ require .NoError (t , err )
407
+
408
+ leafCert , err := x509 .ParseCertificate (leafCertBytes )
409
+ require .NoError (t , err )
410
+
411
+ err = verifyLegacyNameConstraints ([]* x509.Certificate {leafCert , caCert })
412
+ require .NoError (t , err , "signer with name constraints and leaf with SANs should be valid" )
413
+ })
414
+
415
+ t .Run ("ValidationAtSetup" , func (t * testing.T ) {
416
+ fabricMSPConfig := & msp.FabricMSPConfig {
417
+ Name : "ConstraintsMSP" ,
418
+ RootCerts : [][]byte {caCertPem },
419
+ SigningIdentity : & msp.SigningIdentityInfo {
420
+ PublicSigner : leafCertPem ,
421
+ PrivateSigner : & msp.KeyInfo {
422
+ KeyIdentifier : "Certificate Without SAN" ,
423
+ KeyMaterial : leafKeyPem ,
424
+ },
425
+ },
426
+ }
427
+ mspConfig := & msp.MSPConfig {
428
+ Config : protoutil .MarshalOrPanic (fabricMSPConfig ),
429
+ }
430
+
431
+ ks , err := sw .NewFileBasedKeyStore (nil , filepath .Join (configtest .GetDevMspDir (), "keystore" ), true )
432
+ require .NoError (t , err )
433
+ cryptoProvider , err := sw .NewDefaultSecurityLevelWithKeystore (ks )
434
+ require .NoError (t , err )
435
+
436
+ testMSP , err := NewBccspMspWithKeyStore (MSPv1_0 , ks , cryptoProvider )
437
+ require .NoError (t , err )
438
+
439
+ err = testMSP .Setup (mspConfig )
440
+ require .Error (t , err )
441
+ var cie x509.CertificateInvalidError
442
+ require .True (t , errors .As (err , & cie ))
443
+ require .Equal (t , x509 .NameConstraintsWithoutSANs , cie .Reason )
444
+ })
373
445
}
374
446
375
447
func TestIsWellFormed (t * testing.T ) {
0 commit comments