github.com/LanceLRQ/deer-common@v0.0.9-0.20210319081233-e8222ac018a8/persistence/utils.go (about)

     1  package persistence
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"crypto"
     7  	"crypto/rand"
     8  	"crypto/rsa"
     9  	"crypto/sha256"
    10  	"crypto/x509"
    11  	"encoding/pem"
    12  	"github.com/howeyc/gopass"
    13  	"github.com/pkg/errors"
    14  	uuid "github.com/satori/go.uuid"
    15  	"golang.org/x/crypto/openpgp"
    16  	"golang.org/x/crypto/openpgp/armor"
    17  	"io"
    18  	"io/ioutil"
    19  	"os"
    20  	"path"
    21  )
    22  
    23  /* SHA256 */
    24  
    25  func SHA256String(body string) ([]byte, error) {
    26  	return SHA256Bytes([]byte(body))
    27  }
    28  
    29  func SHA256Bytes(body []byte) ([]byte, error) {
    30  	buf := bytes.NewBuffer(body)
    31  	return SHA256Streams([]io.Reader{buf})
    32  }
    33  
    34  func SHA256Streams(streams []io.Reader) ([]byte, error) {
    35  	hash := sha256.New()
    36  	for _, stream := range streams {
    37  		if _, err := io.Copy(hash, stream); err != nil {
    38  			return nil, err
    39  		}
    40  	}
    41  	ret := hash.Sum(nil)
    42  	//hex.EncodeToString(ret)
    43  	return ret, nil
    44  }
    45  
    46  /* RSA Sign */
    47  
    48  func RSA2048SignString(body string, privateKey *rsa.PrivateKey) ([]byte, error) {
    49  	return RSA2048SignBytes([]byte(body), privateKey)
    50  }
    51  
    52  func RSA2048SignBytes(body []byte, privateKey *rsa.PrivateKey) ([]byte, error) {
    53  	hash, err := SHA256Bytes(body)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	return RSA2048Sign(hash, privateKey)
    58  }
    59  
    60  func RSA2048Sign(hash []byte, privateKey *rsa.PrivateKey) ([]byte, error) {
    61  	sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	return sign, nil
    66  }
    67  
    68  /* RSA Verify */
    69  
    70  func RSA2048VerifyString(body string, sign []byte, publicKey *rsa.PublicKey) error {
    71  	return RSA2048VerifyBytes([]byte(body), sign, publicKey)
    72  }
    73  
    74  func RSA2048VerifyBytes(body []byte, sign []byte, publicKey *rsa.PublicKey) error {
    75  	hash, err := SHA256Bytes(body)
    76  	if err != nil {
    77  		return err
    78  	}
    79  	return RSA2048Verify(hash, sign, publicKey)
    80  }
    81  
    82  func RSA2048Verify(hash []byte, sign []byte, publicKey *rsa.PublicKey) error {
    83  	return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash, sign)
    84  }
    85  
    86  func ReadAndParsePublicKey(cert []byte) (*rsa.PublicKey, error) {
    87  	block, _ := pem.Decode(cert)
    88  	if block == nil {
    89  		return nil, errors.New("read public key error")
    90  	}
    91  	//publicKey, err := x509.ParseCertificate(block.Bytes)
    92  	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	return publicKey.(*rsa.PublicKey), nil
    97  	//return publicKey.PublicKey.(*rsa.PublicKey), nil
    98  }
    99  
   100  func ReadAndParsePrivateKey(key []byte) (*rsa.PrivateKey, error) {
   101  	block, _ := pem.Decode(key)
   102  	if block == nil {
   103  		return nil, errors.New("read private key error")
   104  	}
   105  	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  	return privateKey, nil
   110  }
   111  
   112  func ReadPemFile(filename string) ([]byte, error) {
   113  	pemBytes, err := ioutil.ReadFile(filename)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  	return pemBytes, nil
   118  }
   119  
   120  func GetDigitalPEMFromFile(publicKeyFile string, privateKeyFile string) (*DigitalSignPEM, error) {
   121  	publicKey, err := ReadPemFile(publicKeyFile)
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  	privateKey, err := ReadPemFile(privateKeyFile)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  	dp := GetDigitalPEM(publicKey, privateKey)
   130  	return dp, nil
   131  }
   132  
   133  func GetDigitalPEM(publicKey []byte, privateKey []byte) *DigitalSignPEM {
   134  	dp := DigitalSignPEM{}
   135  	if publicKey != nil {
   136  		dp.PublicKeyRaw = publicKey
   137  		pk, err := ReadAndParsePublicKey(publicKey)
   138  		dp.PublicKey = pk
   139  		if err != nil {
   140  			dp.PublicKey = nil
   141  		}
   142  	}
   143  	if privateKey != nil {
   144  		dp.PrivateKeyRaw = privateKey
   145  		pk, err := ReadAndParsePrivateKey(privateKey)
   146  		dp.PrivateKey = pk
   147  		if err != nil {
   148  			dp.PrivateKey = nil
   149  		}
   150  	}
   151  	return &dp
   152  }
   153  
   154  func Gets(reader io.Reader) string {
   155  	buf := make([]byte, 16, 16)
   156  	rd := bufio.NewReader(reader)
   157  	for {
   158  		t, err := rd.ReadByte()
   159  		if err != nil {
   160  			return string(buf)
   161  		}
   162  		buf = append(buf, t)
   163  		if t == 13 || t == 0 {
   164  			break
   165  		}
   166  	}
   167  	return string(buf)
   168  }
   169  
   170  func GetPublicKeyArmorBytes(entity *openpgp.Entity) ([]byte, error) {
   171  	pathname := path.Join("/tmp/" + uuid.NewV4().String() + ".key")
   172  	fp, err := os.Create(pathname)
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  	defer os.Remove(pathname)
   177  
   178  	w, err := armor.Encode(fp, openpgp.PublicKeyType, nil)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  	err = entity.Serialize(w)
   183  	if err != nil {
   184  		return nil, err
   185  	}
   186  	_ = w.Close()
   187  	_ = fp.Close()
   188  
   189  	data, err := ioutil.ReadFile(pathname)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  	return data, nil
   194  }
   195  
   196  func GetArmorPublicKey(gpgKeyFile string, passphrase []byte) (*DigitalSignPEM, error) {
   197  	if gpgKeyFile == "" {
   198  		return nil, errors.Errorf("please set GPG key file path")
   199  	}
   200  	// Open key
   201  	keyRingReader, err := os.Open(gpgKeyFile)
   202  	if err != nil {
   203  		return nil, err
   204  	}
   205  	// Read GPG Keys
   206  	elist, err := openpgp.ReadArmoredKeyRing(keyRingReader)
   207  	if err != nil {
   208  		return nil, err
   209  	}
   210  	if len(elist) < 1 {
   211  		return nil, errors.Errorf("file has no GPG key")
   212  	}
   213  	gpgKey := elist[0].PrivateKey
   214  	if gpgKey.Encrypted {
   215  		if len(passphrase) == 0 {
   216  			passphrase, err = gopass.GetPasswdPrompt("please input passphrase of key> ", true, os.Stdin, os.Stdout)
   217  			if err != nil {
   218  				return nil, err
   219  			}
   220  		}
   221  		err = gpgKey.Decrypt(passphrase)
   222  		if err != nil {
   223  			return nil, err
   224  		}
   225  	}
   226  	publicKeyArmor, err := GetPublicKeyArmorBytes(elist[0])
   227  	if err != nil {
   228  		return nil, err
   229  	}
   230  	return &DigitalSignPEM{
   231  		PrivateKey:   gpgKey.PrivateKey.(*rsa.PrivateKey),
   232  		PublicKeyRaw: publicKeyArmor,
   233  		PublicKey:    elist[0].PrimaryKey.PublicKey.(*rsa.PublicKey),
   234  	}, nil
   235  }