github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/pwk_ac.go (about)

     1  package access_contoller
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/bigzoro/my_simplechain/core/access_contoller/crypto"
     6  	"sync"
     7  	"sync/atomic"
     8  )
     9  
    10  type PWKACProvider struct {
    11  	acService *accessControlService
    12  
    13  	// local org id
    14  	localOrg string
    15  
    16  	// admin list in permissioned public key mode
    17  	adminMember *sync.Map
    18  
    19  	// consensus list in permissioned public key mode
    20  	consensusMember *sync.Map
    21  }
    22  
    23  type adminMemberModel struct {
    24  	publicKey crypto.PublicKey
    25  	pkBytes   []byte
    26  	orgId     string
    27  }
    28  
    29  type consensusMemberModel struct {
    30  	nodeId string
    31  	orgId  string
    32  }
    33  
    34  // VerifyPrincipal verifies if the principal for the resource is met
    35  // 验证给定的 principal 是否满足对应资源的访问控制策略
    36  func (pp *PWKACProvider) VerifyPrincipal(principal Principal) (bool, error) {
    37  	// 安全地读取orgNum的值
    38  	// 它表示链上的组织或信任节点数量。如
    39  	// 果这个数量小于或等于0,则表示链上没有配置组织或信任节点,因此认证失败,并返回相应的错误信息
    40  	if atomic.LoadInt32(&pp.acService.orgNum) <= 0 {
    41  		return false, fmt.Errorf("authentication failed: empty organization list or trusted node list on this chain")
    42  	}
    43  
    44  	// 处理和优化传入的principal对象
    45  	refinedPrincipal, err := pp.refinePrincipal(principal)
    46  	if err != nil {
    47  		return false, fmt.Errorf("authentication failed, [%s]", err.Error())
    48  	}
    49  
    50  	// 检查配置中的IsSkipAccessControl标志是否为真,如果为真,则跳过访问控制检查。
    51  	// 这通常用于调试或测试环境,以便开发者不需要配置完整的访问控制策略即可测试功能
    52  	//if localconf.ChainMakerConfig.DebugConfig.IsSkipAccessControl {
    53  	//	return true, nil
    54  	//}
    55  
    56  	// 查找对应的访问控制策略。如果无法找到策略或出现其他错误,则认证失败,并返回错误
    57  	p, err := pp.acService.lookUpPolicyByResourceName(principal.GetResourceName())
    58  	if err != nil {
    59  		return false, fmt.Errorf("authentication failed, [%s]", err.Error())
    60  	}
    61  
    62  	// 调用verifyPrincipalPolicy方法,传入原始的principal对象、处理后的principal对象和找到的策略对象,
    63  	// 以验证principal是否满足该策略。根据验证结果返回相应的布尔值和可能的错误
    64  	return pp.acService.verifyPrincipalPolicy(principal, refinedPrincipal, p)
    65  }
    66  
    67  // all-in-one validation for signing members: certificate chain/whitelist, signature, policies
    68  // 对传入的 principal 进行一系列验证和细化处理,以确保背书、消息和相关策略都符合安全要求
    69  // 一个全面的验证流程,确保了背书的合法性和消息的完整性
    70  func (pp *PWKACProvider) refinePrincipal(principal Principal) (Principal, error) {
    71  	// 提取背书和验证的签名消息
    72  	endorsements := principal.GetEndorsement()
    73  	msg := principal.GetMessage()
    74  
    75  	// 对背书进行验证和筛选
    76  	// 返回经过验证和筛选的背书列表refinedEndorsement
    77  	refinedEndorsement := pp.RefineEndorsements(endorsements, msg)
    78  	// 如果refinedEndorsement的长度小于或等于0,说明没有任何背书通过验证,因此返回错误信息。
    79  	if len(refinedEndorsement) <= 0 {
    80  		return nil, fmt.Errorf("refine endorsements failed, all endorsers have failed verification")
    81  	}
    82  
    83  	// 创建一个细化后的principal对象
    84  	refinedPrincipal, err := pp.CreatePrincipal(principal.GetResourceName(), refinedEndorsement, msg)
    85  	if err != nil {
    86  		return nil, fmt.Errorf("create principal failed: [%s]", err.Error())
    87  	}
    88  
    89  	return refinedPrincipal, nil
    90  }
    91  
    92  // 验证并筛选一组背书,确保它们来自有效且被信任的成员
    93  // 通过对背书条目的签名进行验证,确保每个背书都来自一个有效的签名者
    94  func (pp *PWKACProvider) RefineEndorsements(endorsements []*EndorsementEntry,
    95  	msg []byte) []*EndorsementEntry {
    96  
    97  	refinedSigners := map[string]bool{}
    98  	var refinedEndorsement []*EndorsementEntry
    99  
   100  	for _, endorsementEntry := range endorsements {
   101  		// 对于每一个背书条目,函数会创建一个新的背书对象,并复制原始背书的相关信息
   102  		endorsement := &EndorsementEntry{
   103  			Signer: &Member{
   104  				OrgId:      endorsementEntry.Signer.OrgId,
   105  				MemberInfo: endorsementEntry.Signer.MemberInfo,
   106  				MemberType: endorsementEntry.Signer.MemberType,
   107  			},
   108  			Signature: endorsementEntry.Signature,
   109  		}
   110  
   111  		// 将签名者的成员信息转换为字符串,以便后续处理
   112  		memInfo := string(endorsement.Signer.MemberInfo)
   113  
   114  		// 根据签名者信息创建一个成员对象,用于验证签名
   115  		remoteMember, err := pp.NewMember(endorsement.Signer)
   116  		if err != nil {
   117  			//pp.acService.log.Infof("new member failed: [%s]", err.Error())
   118  			continue
   119  		}
   120  
   121  		// 使用成员的 Verify 方法验证签名是否有效
   122  		if err := remoteMember.Verify(pp.GetHashAlg(), msg, endorsement.Signature); err != nil {
   123  			//pp.acService.log.Infof("signer member verify signature failed: [%s]", err.Error())
   124  			//pp.acService.log.Debugf("information for invalid signature:\norganization: %s\npubkey: %s\nmessage: %s\n"+
   125  			//	"signature: %s", endorsement.Signer.OrgId, memInfo, hex.Dump(msg), hex.Dump(endorsement.Signature))
   126  			continue
   127  		}
   128  
   129  		// 检查签名者是否已经被处理过,防止重复添加
   130  		if _, ok := refinedSigners[memInfo]; !ok {
   131  			// 如果该签名者未被处理过,则将其标记为已处理,并将相应的背书条目添加到结果列表中
   132  			refinedSigners[memInfo] = true
   133  			refinedEndorsement = append(refinedEndorsement, endorsement)
   134  		}
   135  	}
   136  	return refinedEndorsement
   137  }
   138  
   139  // NewMember creates a member from pb Member
   140  func (pp *PWKACProvider) NewMember(member *Member) (MemberInterface, error) {
   141  	return pp.acService.newPkMember(member, pp.adminMember, pp.consensusMember)
   142  }
   143  
   144  // 基于给定的成员信息创建一个新的公钥成员对象
   145  func (acs *accessControlService) newPkMember(member *Member, adminList,
   146  	consensusList *sync.Map) (MemberInterface, error) {
   147  
   148  	// 尝试从缓存中获取成员对象
   149  	memberCache := acs.getMemberFromCache(member)
   150  	if memberCache != nil {
   151  		return memberCache, nil
   152  	}
   153  
   154  	// 调用newPkMemberFromAcs函数根据提供的成员信息、管理员列表和共识列表以及访问控制服务对象创建一个新的公钥成员对象
   155  	pkMember, err := newPkMemberFromAcs(member, adminList, consensusList, acs)
   156  	if err != nil {
   157  		return nil, fmt.Errorf("new public key member failed: %s", err.Error())
   158  	}
   159  
   160  	// 对新创建的公钥成员进行验证,确保其组织ID与提供的成员信息中的组织ID相匹配。如果不匹配,返回错误信息
   161  	if pkMember.GetOrgId() != member.OrgId && member.OrgId != "" {
   162  		return nil, fmt.Errorf("new public key member failed: member orgId does not match on chain")
   163  	}
   164  
   165  	// 加入缓存
   166  	cached := &memberCached{
   167  		member:    pkMember,
   168  		certChain: nil,
   169  	}
   170  	acs.addMemberToCache(string(member.MemberInfo), cached)
   171  	return pkMember, nil
   172  }
   173  
   174  // CreatePrincipal creates a principal for one time authentication
   175  func (pp *PWKACProvider) CreatePrincipal(resourceName string, endorsements []*EndorsementEntry,
   176  	message []byte) (Principal, error) {
   177  	return pp.acService.createPrincipal(resourceName, endorsements, message)
   178  }
   179  
   180  // GetHashAlg return hash algorithm the access control provider uses
   181  func (pp *PWKACProvider) GetHashAlg() string {
   182  	return pp.acService.hashType
   183  }