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

     1  package access_contoller
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/hex"
     6  	"fmt"
     7  	bccrypto "github.com/bigzoro/my_simplechain/core/access_contoller/crypto"
     8  	"github.com/bigzoro/my_simplechain/core/access_contoller/crypto/asym"
     9  	"github.com/mr-tron/base58"
    10  	"sync"
    11  )
    12  
    13  // an instance whose member type is a certificate
    14  // 定义了一个区块链网络成员的核心属性,包括其身份、所属组织、公钥信息、角色和使用的哈希类型。
    15  // 这样的设计使得区块链网络能够高效地进行身份验证、权限控制和数据完整性校验
    16  type pkMember struct {
    17  
    18  	// pem public key
    19  	// 成员的唯一标识符,通常是基于成员的公钥信息生成的。这个ID可以用来在网络中唯一地标识这个成员
    20  	id string
    21  
    22  	// organization identity who owns this member
    23  	// orgId表示拥有这个成员的组织的标识符。在多组织的区块链网络中,这个字段用于区分成员属于哪个组织
    24  	orgId string
    25  
    26  	// public key uid
    27  	// uid是公钥的唯一标识符,用于在可能存在多个公钥的情况下区分不同的公钥
    28  	uid string
    29  
    30  	// the public key used for authentication
    31  	// 存储用于身份验证的公钥。在区块链网络中,公钥和私钥对用于签名和验证签名,以确保交易或消息的真实性和完整性
    32  	pk bccrypto.PublicKey
    33  
    34  	// role of this member
    35  	// role字段表示这个成员在网络中的角色。不同的角色可能有不同的权限和责任
    36  	role Role
    37  
    38  	// hash type from chain configuration
    39  	// hashType字段指定了链配置中使用的哈希类型。哈希函数用于生成数据的哈希值,是区块链技术中确保数据不可篡改的关键机制之一
    40  	hashType string
    41  }
    42  
    43  func (pm *pkMember) GetPk() bccrypto.PublicKey {
    44  	return pm.pk
    45  }
    46  
    47  // GetMemberId returns the identity of this member (non-uniqueness)
    48  func (pm *pkMember) GetMemberId() string {
    49  	return pm.id
    50  }
    51  
    52  // GetOrgId returns the organization id which this member belongs to
    53  func (pm *pkMember) GetOrgId() string {
    54  	return pm.orgId
    55  }
    56  
    57  // GetRole returns roles of this member
    58  func (pm *pkMember) GetRole() Role {
    59  	return pm.role
    60  }
    61  
    62  // GetUid returns the identity of this member (unique)
    63  func (pm *pkMember) GetUid() string {
    64  	return pm.uid
    65  }
    66  
    67  func newPkMemberFromAcs(member *Member, adminList, consensusList *sync.Map,
    68  	acs *accessControlService) (*pkMember, error) {
    69  
    70  	// 检查成员类型是否为公钥,如果不是则返回错误
    71  	if member.MemberType != MemberType_PUBLIC_KEY {
    72  		return nil, fmt.Errorf("new public key member failed: memberType and authType do not match")
    73  	}
    74  
    75  	// 尝试从成员信息中解析公钥,如果解析失败则返回
    76  	pk, err := asym.PublicKeyFromPEM(member.MemberInfo)
    77  	if err != nil {
    78  		return nil, fmt.Errorf("new public key member failed: parse the public key from PEM failed")
    79  	}
    80  
    81  	// 获取公钥的字节表示
    82  	pkBytes, err := pk.Bytes()
    83  	if err != nil {
    84  		return nil, fmt.Errorf("new public key member failed: %s", err.Error())
    85  	}
    86  
    87  	// 尝试从管理员列表中加载公钥对应的管理员成员,如果存在,则创建并返回一个新的公钥成员实例
    88  	adminMember, ok := adminList.Load(hex.EncodeToString(pkBytes))
    89  	if ok {
    90  		admin, _ := adminMember.(*adminMemberModel)
    91  		return newPkMemberFromParam(admin.orgId, admin.pkBytes, RoleAdmin, acs.hashType)
    92  	}
    93  
    94  	// 如果公钥不是管理员,则尝试创建与公钥关联的 libp2p 节点 ID
    95  	//var nodeId string
    96  	//nodeId, err = CreateLibp2pPeerIdWithPublicKey(pk)
    97  	//if err != nil {
    98  	//	return nil, fmt.Errorf("new public key member failed: create libp2p peer id with pk failed")
    99  	//}
   100  	//
   101  	//// 尝试从共识列表中加载节点 ID 对应的共识成员,如果存在,则创建并返回一个新的成员实例
   102  	//consensusMember, ok := consensusList.Load(nodeId)
   103  	//if ok {
   104  	//	consensus, _ := consensusMember.(*consensusMemberModel)
   105  	//	return newPkMemberFromParam(consensus.orgId, pkBytes, RoleConsensusNode, acs.hashType)
   106  	//}
   107  
   108  	// 如果公钥既不是管理员也不是共识成员,则尝试从链上读取公钥信息
   109  	//publicKeyIdex := pubkeyHash(pkBytes)
   110  	//publicKeyInfoBytes, err := acs.dataStore.ReadObject(syscontract.SystemContract_PUBKEY_MANAGE.String(),
   111  	//	[]byte(publicKeyIdex))
   112  	//if err != nil {
   113  	//	return nil, fmt.Errorf("new public key member failed: %s", err.Error())
   114  	//}
   115  
   116  	// 如果链上不存在该公钥信息,则返回错误
   117  	//if publicKeyInfoBytes == nil {
   118  	//	return nil, fmt.Errorf("new public key member failed: the public key doesn't belong to a member on chain")
   119  	//}
   120  
   121  	// 解析链上的公钥信息
   122  	//var publickInfo PKInfo
   123  	//err = proto.Unmarshal(publicKeyInfoBytes, &publickInfo)
   124  	//if err != nil {
   125  	//	return nil, fmt.Errorf("new public key member failed: %s", err.Error())
   126  	//}
   127  	//
   128  	//// 根据链上公钥信息创建并返回一个新的公钥成员实例
   129  	//return newPkMemberFromParam(publickInfo.OrgId, pkBytes,
   130  	//	protocol.Role(publickInfo.Role), acs.hashType)
   131  
   132  	return nil, nil
   133  }
   134  
   135  // 定义函数newPkMemberFromParam,它接收一个组织ID、公钥字节、角色和哈希类型,返回一个公钥成员和可能的错误。
   136  func newPkMemberFromParam(orgId string, pkBytes []byte, role Role,
   137  	hashType string) (*pkMember, error) {
   138  
   139  	// 尝试从哈希算法映射中查找给定的哈希类型
   140  	hash, ok := bccrypto.HashAlgoMap[hashType]
   141  	if !ok {
   142  		return nil, fmt.Errorf("sign failed: unsupport hash type")
   143  	}
   144  
   145  	// 初始化一个pkMember结构体实例。
   146  	var pkMem pkMember
   147  	pkMem.orgId = orgId
   148  	pkMem.hashType = hashType
   149  
   150  	// 尝试从公钥字节中解析公钥,如果失败,则返回错误。
   151  	pk, err := asym.PublicKeyFromDER(pkBytes)
   152  	if err != nil {
   153  		return nil, fmt.Errorf("setup pk member failed, err: %s", err.Error())
   154  	}
   155  
   156  	// 设置pkMember结构体的公钥和角色字段。
   157  	pkMem.pk = pk
   158  	pkMem.role = role
   159  
   160  	// 计算公钥的主题密钥标识符(SKI),这通常用于唯一标识公钥。
   161  	ski, err := ComputeSKI(hash, pk.ToStandardKey())
   162  	if err != nil {
   163  		return nil, fmt.Errorf("setup pk member failed, err: %s", err.Error())
   164  	}
   165  
   166  	// 将SKI编码为十六进制字符串,并设置为pkMember的UID。
   167  	pkMem.uid = hex.EncodeToString(ski)
   168  
   169  	// 将公钥转换为PEM格式的字符串,如果失败,则返回错误。
   170  	pkPem, err := pk.String()
   171  	if err != nil {
   172  		return nil, fmt.Errorf("setup pk member failed, err: %s", err.Error())
   173  	}
   174  
   175  	// 设置pkMember的ID为公钥的PEM字符串。
   176  	pkMem.id = pkPem
   177  
   178  	// 返回初始化完成的pkMember实例和nil错误。
   179  	return &pkMem, nil
   180  }
   181  
   182  func pubkeyHash(pubkey []byte) string {
   183  	pkHash := sha256.Sum256(pubkey)
   184  	strPkHash := base58.Encode(pkHash[:])
   185  	return strPkHash
   186  }
   187  
   188  //// CreateLibp2pPeerIdWithPublicKey create a peer.ID with crypto.PublicKey.
   189  //func CreateLibp2pPeerIdWithPublicKey(publicKey crypto.PublicKey) (string, error) {
   190  //	pubKey, err := ParseGoPublicKeyToPubKey(publicKey.ToStandardKey())
   191  //	if err != nil {
   192  //		return "", err
   193  //	}
   194  //	pid, err := libp2ppeer.IDFromPublicKey(pubKey)
   195  //	if err != nil {
   196  //		return "", err
   197  //	}
   198  //	return pid.Pretty(), err
   199  //}
   200  //
   201  //// ParseGoPublicKeyToPubKey parse a go crypto PublicKey to a libp2p crypto PubKey.
   202  //func ParseGoPublicKeyToPubKey(publicKey bccrypto.PublicKey) (libp2pcrypto.PubKey, error) {
   203  //	switch p := publicKey.(type) {
   204  //	case *ecdsa.PublicKey:
   205  //		if p.Curve == sm2.P256Sm2() {
   206  //			b, err := tjx509.MarshalPKIXPublicKey(p)
   207  //			if err != nil {
   208  //				return nil, err
   209  //			}
   210  //			pub, err := tjx509.ParseSm2PublicKey(b)
   211  //			if err != nil {
   212  //				return nil, err
   213  //			}
   214  //			return libp2pcrypto.NewSM2PublicKey(pub), nil
   215  //		}
   216  //		if p.Curve == btcec.S256() {
   217  //			return (*libp2pcrypto.Secp256k1PublicKey)(p), nil
   218  //		}
   219  //		return libp2pcrypto.NewECDSAPublicKey(p), nil
   220  //
   221  //	case *sm2.PublicKey:
   222  //		return libp2pcrypto.NewSM2PublicKey(p), nil
   223  //	case *rsa.PublicKey:
   224  //		return libp2pcrypto.NewRsaPublicKey(*p), nil
   225  //	default:
   226  //		return nil, errors.New("unsupported public key type")
   227  //	}
   228  //}
   229  
   230  type signingPKMember struct {
   231  	// Extends Identity
   232  	pkMember
   233  
   234  	// Sign the message
   235  	sk bccrypto.PrivateKey
   236  }
   237  
   238  // Verify verifies a signature over some message using this member
   239  func (pm *pkMember) Verify(hashType string, msg []byte, sig []byte) error {
   240  	hash, ok := bccrypto.HashAlgoMap[hashType]
   241  	if !ok {
   242  		return fmt.Errorf("cert member verify signature failed: unsupport hash type")
   243  	}
   244  
   245  	ok, err := pm.pk.VerifyWithOpts(msg, sig, &bccrypto.SignOpts{
   246  		Hash: hash,
   247  		UID:  bccrypto.CRYPTO_DEFAULT_UID,
   248  	})
   249  	if err != nil {
   250  		return fmt.Errorf("cert member verify signature failed: [%s]", err.Error())
   251  	}
   252  	if !ok {
   253  		return fmt.Errorf("cert member verify signature failed: invalid signature")
   254  	}
   255  	return nil
   256  }
   257  
   258  // When using public key instead of certificate,
   259  // hashType is used to specify the hash algorithm while the signature algorithm is decided by the public key itself.
   260  func (spm *signingPKMember) Sign(hashType string, msg []byte) ([]byte, error) {
   261  	hash, ok := bccrypto.HashAlgoMap[hashType]
   262  	if !ok {
   263  		return nil, fmt.Errorf("sign failed: unsupport hash type")
   264  	}
   265  	return spm.sk.SignWithOpts(msg, &bccrypto.SignOpts{
   266  		Hash: hash,
   267  		UID:  bccrypto.CRYPTO_DEFAULT_UID,
   268  	})
   269  }
   270  
   271  // GetMember returns Member
   272  func (pm *pkMember) GetMember() (*Member, error) {
   273  	memberInfo, err := pm.pk.String()
   274  	if err != nil {
   275  		return nil, fmt.Errorf("get pb member failed: %s", err.Error())
   276  	}
   277  	return &Member{
   278  		OrgId:      pm.orgId,
   279  		MemberInfo: []byte(memberInfo),
   280  		MemberType: MemberType_PUBLIC_KEY,
   281  	}, nil
   282  }