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 }