package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"
)

// LoadCert 读取证书文件
func LoadCert(path string) (*x509.Certificate, error) {
	//1.打开磁盘的公钥文件
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	fileInfo, err := file.Stat()
	if err != nil {
		return nil, err
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	if err != nil {
		return nil, err
	}
	//2.使用pem解码得到pem.Block结构体变量
	block, _ := pem.Decode(buf)

	//证书解析
	certBody, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		return nil, err
	}
	return certBody, nil
}

// LoadPriKey 读取私钥文件
func LoadPriKey(path string) (*rsa.PrivateKey, error) {
	//1.打开磁盘的私钥文件
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	//2.将私钥文件中的内容读出
	fileInfo, err := file.Stat()
	if err != nil {
		return nil, err
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	if err != nil {
		return nil, err
	}
	//3.使用pem对数据解码，得到pem.Block结构体变量
	block, _ := pem.Decode(buf)
	//4.x509将数据解析成私钥结构体得到私钥
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	return privateKey, nil
}

// SignRSA RSA 签名
func SignRSA(plainText []byte, priKey *rsa.PrivateKey) ([]byte, error) {
	//1.创建一个哈希对象
	hash := sha256.New()
	//2.给哈希对象添加数据
	_, err := hash.Write(plainText)
	if err != nil {
		return nil, err
	}
	//3.计算哈希值
	hashed := hash.Sum(nil)
	//4.使用rsa中的函数对散列值签名
	signText, err := rsa.SignPKCS1v15(rand.Reader, priKey, crypto.SHA256, hashed)
	if err != nil {
		return nil, err
	}
	return signText, nil
}

func VerifyRSA(plainText, signText []byte, cert *x509.Certificate) error {
	publicKeyDer, err := x509.MarshalPKIXPublicKey(cert.PublicKey)
	if err != nil {
		return err
	}
	pubKeyInterface, err := x509.ParsePKIXPublicKey(publicKeyDer)
	if err != nil {
		return err
	}
	//进行类型断言得到公钥结构体
	publicKey := pubKeyInterface.(*rsa.PublicKey)

	//* 创建哈希接口
	hash := sha256.New()
	//* 添加数据
	hash.Write(plainText)
	//* 哈希运算
	hasded := hash.Sum(nil)
	//
	//6.签名认证
	err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hasded, signText)
	if err != nil {
		return err
	}
	return nil
}

var rootCertPool *x509.CertPool

func VerifyCert(cert *x509.Certificate) error {
	//block, _ := pem.Decode([]byte(certPEM))
	//if block == nil {
	//	return fmt.Errorf("failed to parse certificate PEM")
	//}
	//cert, err := x509.ParseCertificate(block.Bytes)
	//if err != nil {
	//	return fmt.Errorf("failed to parse certificate: %v", err.Error())
	//}

	opts := x509.VerifyOptions{
		Roots: rootCertPool,
	}

	if _, err := cert.Verify(opts); err != nil {
		return fmt.Errorf("failed to verify certificate: %v", err.Error())
	}

	return nil
}
