gitee.com/lh-her-team/common@v1.5.1/helper/net_helper.go (about)

     1  package helper
     2  
     3  import (
     4  	goCrypto "crypto"
     5  	"crypto/ecdsa"
     6  	"crypto/rsa"
     7  	"encoding/pem"
     8  	"errors"
     9  	"fmt"
    10  
    11  	"gitee.com/lh-her-team/common/crypto"
    12  	"gitee.com/lh-her-team/common/helper/libp2pcrypto"
    13  	"gitee.com/lh-her-team/common/helper/libp2ppeer"
    14  	"github.com/btcsuite/btcd/btcec"
    15  	ma "github.com/multiformats/go-multiaddr"
    16  	"github.com/tjfoc/gmsm/sm2"
    17  	tjx509 "github.com/tjfoc/gmsm/x509"
    18  )
    19  
    20  // GetNodeUidFromAddr get the unique id of node from an addr. 从地址中截取出节点ID
    21  func GetNodeUidFromAddr(addr string) (string, error) {
    22  	maAddr, err := ma.NewMultiaddr(addr)
    23  	if err != nil {
    24  		return "", err
    25  	}
    26  	_, last := ma.SplitLast(maAddr)
    27  	res, err := last.ValueForProtocol(ma.P_P2P)
    28  	if err != nil {
    29  		return "", fmt.Errorf("wrong address, %s", err.Error())
    30  	}
    31  	return res, nil
    32  }
    33  
    34  // GetLibp2pPeerIdFromCert create a peer.ID with pubKey that contains in cert.
    35  func GetLibp2pPeerIdFromCert(certPemBytes []byte) (string, error) {
    36  	var block *pem.Block
    37  	block, _ = pem.Decode(certPemBytes)
    38  	if block == nil {
    39  		return "", errors.New("empty pem block")
    40  	}
    41  	if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
    42  		return "", errors.New("not certificate pem")
    43  	}
    44  	return GetLibp2pPeerIdFromCertDer(block.Bytes)
    45  }
    46  
    47  // GetLibp2pPeerIdFromCertDer create a peer.ID with pubKey that contains in cert.
    48  func GetLibp2pPeerIdFromCertDer(certDerBytes []byte) (string, error) {
    49  	cert, err := tjx509.ParseCertificate(certDerBytes)
    50  	if err != nil {
    51  		return "", err
    52  	}
    53  	pubKey, err := ParseGoPublicKeyToPubKey(cert.PublicKey)
    54  	if err != nil {
    55  		return "", err
    56  	}
    57  	pid, err := libp2ppeer.IDFromPublicKey(pubKey)
    58  	if err != nil {
    59  		return "", err
    60  	}
    61  	return pid.Pretty(), err
    62  }
    63  
    64  // CreateLibp2pPeerIdWithPrivateKey create a peer.ID with crypto.PrivateKey.
    65  func CreateLibp2pPeerIdWithPrivateKey(privateKey crypto.PrivateKey) (string, error) {
    66  	return CreateLibp2pPeerIdWithPublicKey(privateKey.PublicKey())
    67  }
    68  
    69  // CreateLibp2pPeerIdWithPublicKey create a peer.ID with crypto.PublicKey.
    70  func CreateLibp2pPeerIdWithPublicKey(publicKey crypto.PublicKey) (string, error) {
    71  	pubKey, err := ParseGoPublicKeyToPubKey(publicKey.ToStandardKey())
    72  	if err != nil {
    73  		return "", err
    74  	}
    75  	pid, err := libp2ppeer.IDFromPublicKey(pubKey)
    76  	if err != nil {
    77  		return "", err
    78  	}
    79  	return pid.Pretty(), err
    80  }
    81  
    82  // ParseGoPublicKeyToPubKey parse a go crypto PublicKey to a libp2p crypto PubKey.
    83  func ParseGoPublicKeyToPubKey(publicKey goCrypto.PublicKey) (libp2pcrypto.PubKey, error) {
    84  	switch p := publicKey.(type) {
    85  	case *ecdsa.PublicKey:
    86  		if p.Curve == sm2.P256Sm2() {
    87  			b, err := tjx509.MarshalPKIXPublicKey(p)
    88  			if err != nil {
    89  				return nil, err
    90  			}
    91  			pub, err := tjx509.ParseSm2PublicKey(b)
    92  			if err != nil {
    93  				return nil, err
    94  			}
    95  			return libp2pcrypto.NewSM2PublicKey(pub), nil
    96  		}
    97  		if p.Curve == btcec.S256() {
    98  			return (*libp2pcrypto.Secp256k1PublicKey)(p), nil
    99  		}
   100  		return libp2pcrypto.NewECDSAPublicKey(p), nil
   101  	case *sm2.PublicKey:
   102  		return libp2pcrypto.NewSM2PublicKey(p), nil
   103  	case *rsa.PublicKey:
   104  		return libp2pcrypto.NewRsaPublicKey(*p), nil
   105  	default:
   106  		return nil, errors.New("unsupported public key type")
   107  	}
   108  }
   109  
   110  // P2pAddressFormatVerify verify a node address format.
   111  func P2pAddressFormatVerify(address string) bool {
   112  	mA, err := ma.NewMultiaddr(address)
   113  	if err != nil {
   114  		return false
   115  	}
   116  	_, err = libp2ppeer.AddrInfoFromP2pAddr(mA)
   117  	return err == nil
   118  }