gitee.com/Mydawng/fabric-ca@v2.0.0-alpha.0.20201214145411-9ea68369cb61+incompatible/lib/serverenroll_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lib
     8  
     9  import (
    10  	"github.com/cloudflare/cfssl/signer"
    11  	"github.com/hyperledger/fabric-ca/internal/pkg/api"
    12  	"github.com/hyperledger/fabric-ca/internal/pkg/util"
    13  	dbuser "github.com/hyperledger/fabric-ca/lib/server/user"
    14  	"github.com/stretchr/testify/assert"
    15  	"os"
    16  	"testing"
    17  	"time"
    18  )
    19  
    20  func TestStateUpdate(t *testing.T) {
    21  	cleanTestSlateSE(t)
    22  	defer cleanTestSlateSE(t)
    23  
    24  	var err error
    25  	srv := TestGetRootServer(t)
    26  
    27  	err = srv.Start()
    28  	assert.NoError(t, err, "Failed to start server")
    29  
    30  	client := getTestClient(rootPort)
    31  	_, err = client.Enroll(&api.EnrollmentRequest{
    32  		Name:   "admin",
    33  		Secret: "adminpw",
    34  	})
    35  	assert.NoError(t, err, "Failed to enroll 'admin' user")
    36  
    37  	registry := srv.CA.DBAccessor()
    38  	userInfo, err := registry.GetUser("admin", nil)
    39  	assert.NoError(t, err, "Failed to get user 'admin' from database")
    40  	// User state should have gotten updated to 1 after a successful enrollment
    41  	if userInfo.(*dbuser.Impl).State != 1 {
    42  		t.Error("Incorrect state set for user")
    43  	}
    44  
    45  	// Send bad CSR to cause the enroll to fail but the login to succeed
    46  	reqNet := &api.EnrollmentRequestNet{}
    47  	reqNet.SignRequest.Request = "badcsr"
    48  	body, err := util.Marshal(reqNet, "SignRequest")
    49  	assert.NoError(t, err, "Failed to marshal enroll request")
    50  
    51  	// Send the CSR to the fabric-ca server with basic auth header
    52  	post, err := client.newPost("enroll", body)
    53  	assert.NoError(t, err, "Failed to create post request")
    54  	post.SetBasicAuth("admin", "adminpw")
    55  	err = client.SendReq(post, nil)
    56  	if assert.Error(t, err, "Should have failed due to bad csr") {
    57  		assert.Contains(t, err.Error(), "CSR Decode failed")
    58  	}
    59  
    60  	// State should not have gotten updated because the enrollment failed
    61  	userInfo, err = registry.GetUser("admin", nil)
    62  	assert.NoError(t, err, "Failed to get user 'admin' from database")
    63  	if userInfo.(*dbuser.Impl).State != 1 {
    64  		t.Error("Incorrect state set for user")
    65  	}
    66  
    67  	err = srv.Stop()
    68  	assert.NoError(t, err, "Failed to stop server")
    69  
    70  }
    71  
    72  func cleanTestSlateSE(t *testing.T) {
    73  	err := os.RemoveAll(rootDir)
    74  	if err != nil {
    75  		t.Errorf("RemoveAll failed: %s", err)
    76  	}
    77  	err = os.RemoveAll("../testdata/msp")
    78  	if err != nil {
    79  		t.Errorf("RemoveAll failed: %s", err)
    80  	}
    81  }
    82  
    83  func TestPasswordLimit(t *testing.T) {
    84  	cleanTestSlateSE(t)
    85  	defer cleanTestSlateSE(t)
    86  
    87  	passLimit := 3
    88  
    89  	srv := TestGetRootServer(t)
    90  	srv.CA.Config.Cfg.Identities.PasswordAttempts = passLimit
    91  	err := srv.Start()
    92  	util.FatalError(t, err, "Failed to start server")
    93  	defer srv.Stop()
    94  
    95  	client := getTestClient(rootPort)
    96  	enrollResp, err := client.Enroll(&api.EnrollmentRequest{
    97  		Name:   "admin",
    98  		Secret: "adminpw",
    99  	})
   100  	util.FatalError(t, err, "Failed to enroll 'admin' user")
   101  	admin := enrollResp.Identity
   102  
   103  	_, err = admin.Register(&api.RegistrationRequest{
   104  		Name:   "user1",
   105  		Secret: "user1pw",
   106  	})
   107  	util.FatalError(t, err, "Failed to register 'user1' user")
   108  
   109  	// Reach maximum incorrect password limit
   110  	for i := 0; i < passLimit; i++ {
   111  		_, err = client.Enroll(&api.EnrollmentRequest{
   112  			Name:   "user1",
   113  			Secret: "badpass",
   114  		})
   115  		assert.Error(t, err, "Enroll for user 'user1' should fail due to bad password")
   116  	}
   117  	_, err = client.Enroll(&api.EnrollmentRequest{
   118  		Name:   "user1",
   119  		Secret: "badpass",
   120  	})
   121  	util.ErrorContains(t, err, "73", "Should fail, incorrect password limit reached")
   122  
   123  	// Admin modifying identity, confirm that just modifying identity does not reset attempt
   124  	// count. Incorrect password attempt count should only be reset to zero, if password
   125  	// is modified.
   126  	modReq := &api.ModifyIdentityRequest{
   127  		ID: "user1",
   128  	}
   129  
   130  	modReq.Type = "client"
   131  	_, err = admin.ModifyIdentity(modReq)
   132  	assert.NoError(t, err, "Failed to modify identity")
   133  
   134  	_, err = client.Enroll(&api.EnrollmentRequest{
   135  		Name:   "user1",
   136  		Secret: "user1pw",
   137  	})
   138  	assert.Error(t, err, "Should failed to enroll")
   139  
   140  	// Admin reset password
   141  	modReq.Secret = "newPass"
   142  	_, err = admin.ModifyIdentity(modReq)
   143  	assert.NoError(t, err, "Failed to modify identity")
   144  
   145  	_, err = client.Enroll(&api.EnrollmentRequest{
   146  		Name:   "user1",
   147  		Secret: "newPass",
   148  	})
   149  	assert.NoError(t, err, "Failed to enroll using new password after admin reset password")
   150  
   151  	// Test that if password is entered correctly before reaching incorrect password limit,
   152  	// the incorrect password count is reset back to 0
   153  	_, err = client.Enroll(&api.EnrollmentRequest{
   154  		Name:   "user1",
   155  		Secret: "badPass",
   156  	})
   157  	assert.Error(t, err, "Enroll for user 'user1' should fail due to bad password")
   158  
   159  	registry := srv.CA.DBAccessor()
   160  	user1, err := registry.GetUser("user1", nil)
   161  	util.FatalError(t, err, "Failed to get 'user1' from database")
   162  	assert.Equal(t, 1, user1.GetFailedLoginAttempts())
   163  
   164  	_, err = client.Enroll(&api.EnrollmentRequest{
   165  		Name:   "user1",
   166  		Secret: "newPass",
   167  	})
   168  	assert.NoError(t, err, "Failed to enroll user with correct password")
   169  
   170  	user1, err = registry.GetUser("user1", nil)
   171  	util.FatalError(t, err, "Failed to get 'user1' from database")
   172  	assert.Equal(t, 0, user1.GetFailedLoginAttempts())
   173  }
   174  
   175  func TestCertificateExpiration(t *testing.T) {
   176  	cleanTestSlateSE(t)
   177  	defer cleanTestSlateSE(t)
   178  
   179  	srv := TestGetRootServer(t)
   180  	err := srv.Start()
   181  	util.FatalError(t, err, "Failed to start server")
   182  	defer srv.Stop()
   183  
   184  	caCertPem, _ := srv.CA.getCACert()
   185  	caCert, _ := util.GetX509CertificateFromPEM(caCertPem)
   186  
   187  	client := getTestClient(rootPort)
   188  
   189  	csrPEM, _, err := client.GenCSR(&api.CSRInfo{CN: "admin"}, "admin")
   190  	assert.NoError(t, err, "Failed to generate CSR")
   191  
   192  	reqNet := &api.EnrollmentRequestNet{
   193  		SignRequest: signer.SignRequest{
   194  			Request: string(csrPEM),
   195  			// requesting certificate with validity time wider then CA cert
   196  			NotBefore: caCert.NotBefore.Add(-1 * time.Hour),
   197  			NotAfter:  caCert.NotAfter.Add(24 * time.Hour),
   198  		},
   199  	}
   200  
   201  	body, err := util.Marshal(reqNet, "SignRequest")
   202  	assert.NoError(t, err, "Failed to marshal enroll request")
   203  
   204  	// Send the CSR to the fabric-ca server with basic auth header
   205  	post, err := client.newPost("enroll", body)
   206  	assert.NoError(t, err, "Failed to create post request")
   207  	post.SetBasicAuth("admin", "adminpw")
   208  
   209  	var result api.EnrollmentResponseNet
   210  	err = client.SendReq(post, &result)
   211  	assert.NoError(t, err, "Failed to enroll")
   212  
   213  	// verify response
   214  	certBytes, err := util.B64Decode(result.Cert)
   215  	assert.NoError(t, err, "Failed to convert certificate")
   216  	userCert, err := util.GetX509CertificateFromPEM(certBytes)
   217  	assert.NoError(t, err, "Failed to extract certificate from enroll response")
   218  
   219  	assert.False(t, userCert.NotBefore.Before(caCert.NotBefore),
   220  		"user certificate NotBefore %v is before CA cert NotBefore %v", userCert.NotBefore, caCert.NotBefore)
   221  	assert.False(t, userCert.NotAfter.After(caCert.NotAfter),
   222  		"user certificate NotAfter %v is after CA cert NotAfter %v", userCert.NotAfter, caCert.NotAfter)
   223  }