github.com/dddengyunjie/fabric-ca@v0.0.0-20190606043049-92df60ae2f0f/lib/gmca.go (about)

     1  package lib
     2  
     3  import (
     4  	"crypto/x509"
     5  	"crypto/x509/pkix"
     6  	"encoding/asn1"
     7  	"encoding/hex"
     8  	"fmt"
     9  	"net"
    10  	"net/mail"
    11  	"time"
    12  
    13  	"crypto"
    14  	"crypto/rand"
    15  	"encoding/pem"
    16  	"io"
    17  	"math/big"
    18  
    19  	"github.com/cloudflare/cfssl/certdb"
    20  	"github.com/cloudflare/cfssl/csr"
    21  	"github.com/cloudflare/cfssl/log"
    22  	"github.com/hyperledger/fabric/bccsp"
    23  	"github.com/hyperledger/fabric/bccsp/gm"
    24  	"github.com/tjfoc/gmsm/sm2"
    25  
    26  	"github.com/cloudflare/cfssl/signer"
    27  	"github.com/hyperledger/fabric-ca/util"
    28  )
    29  
    30  //证书签名
    31  func signCert(req signer.SignRequest, ca *CA) (cert []byte, err error) {
    32  	/*csr := parseCertificateRequest()
    33  	cert, err := sm2.CreateCertificateToMem(template, rootca, csr.pubkey, rootca.privkey)
    34  	sm2Cert, err := sm2.parseCertificateFromMem(cert)
    35  
    36  	var certRecord = certdb.CertificateRecord{
    37  		Serial:  sm2Cert.SerialNumber.String(),
    38  		AKI:     hex.EncodeToString(sm2Cert.AuthorityKeyId),
    39  		CALabel: req.Label,
    40  		Status:  "good",
    41  		Expiry:  sm2Cert.NotAfter,
    42  		PEM:     string(cert),
    43  	}*/
    44  
    45  	block, _ := pem.Decode([]byte(req.Request))
    46  	if block == nil {
    47  		return nil, fmt.Errorf("decode error")
    48  	}
    49  	if block.Type != "NEW CERTIFICATE REQUEST" && block.Type != "CERTIFICATE REQUEST" {
    50  		return nil, fmt.Errorf("not a csr")
    51  	}
    52  	template, err := parseCertificateRequest(block.Bytes)
    53  	if err != nil {
    54  		log.Infof("xxxx gmca.go ParseCertificateRequest error:[%s]", err)
    55  		return nil, err
    56  	}
    57  
    58  	certfile := ca.Config.CA.Certfile
    59  	//certfile := req.Profile
    60  	log.Infof("^^^^^^^^^^^^^^^^^^^^^^^certifle = %s", certfile)
    61  	rootkey, _, x509cert, err := util.GetSignerFromCertFile(certfile, ca.csp)
    62  	if err != nil {
    63  
    64  		return nil, err
    65  	}
    66  	log.Infof("^^^^^^^^^^^^^^^^^^^^^^^x509cert = %v", x509cert)
    67  	rootca := ParseX509Certificate2Sm2(x509cert)
    68  
    69  	cert, err = gm.CreateCertificateToMem(template, rootca, rootkey)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	log.Infof("^^^^^^^^^^^^^^^^^^^^^^^template = %v\n cert = %v\n Type = %T", template, cert, template.PublicKey)
    74  	clientCert, err := sm2.ReadCertificateFromMem(cert)
    75  	log.Info("==================== Exit ParseCertificate")
    76  	if err == nil {
    77  		log.Infof("xxxx gmca.go signCert ok the sign cert len [%d]", len(cert))
    78  	}
    79  
    80  	var certRecord = certdb.CertificateRecord{
    81  		Serial:  clientCert.SerialNumber.String(),
    82  		AKI:     hex.EncodeToString(clientCert.AuthorityKeyId),
    83  		CALabel: req.Label,
    84  		Status:  "good",
    85  		Expiry:  clientCert.NotAfter,
    86  		PEM:     string(cert),
    87  	}
    88  	//aki := hex.EncodeToString(cert.AuthorityKeyId)
    89  	//serial := util.GetSerialAsHex(cert.SerialNumber)
    90  
    91  	err = ca.certDBAccessor.InsertCertificate(certRecord)
    92  	if err == nil {
    93  		log.Info("=====================error InsertCertificate!")
    94  	}
    95  
    96  	return
    97  }
    98  
    99  //生成证书
   100  func createGmSm2Cert(key bccsp.Key, req *csr.CertificateRequest, priv crypto.Signer) (cert []byte, err error) {
   101  	log.Infof("xxx xxx in gmca.go  createGmSm2Cert...key :%T", key)
   102  
   103  	csrPEM, err := generate(priv, req, key)
   104  	if err != nil {
   105  		log.Infof("xxxxxxxxxxxxx create csr error:%s", err)
   106  	}
   107  	log.Infof("xxxxxxxxxxxxx create gm csr completed!")
   108  	block, _ := pem.Decode(csrPEM)
   109  	if block == nil {
   110  		return nil, fmt.Errorf("sm2 csr DecodeFailed")
   111  	}
   112  
   113  	if block.Type != "NEW CERTIFICATE REQUEST" && block.Type != "CERTIFICATE REQUEST" {
   114  		return nil, fmt.Errorf("sm2 not a csr")
   115  	}
   116  	sm2Template, err := parseCertificateRequest(block.Bytes)
   117  	if err != nil {
   118  		log.Infof("parseCertificateRequest return err:%s", err)
   119  		return nil, err
   120  	}
   121  	log.Infof("key is %T   ---%T", sm2Template.PublicKey, sm2Template)
   122  	cert, err = gm.CreateCertificateToMem(sm2Template, sm2Template, key)
   123  	return cert, err
   124  }
   125  
   126  //证书请求转换成证书  参数为  block .Bytes
   127  func parseCertificateRequest(csrBytes []byte) (template *sm2.Certificate, err error) {
   128  	csrv, err := sm2.ParseCertificateRequest(csrBytes)
   129  	if err != nil {
   130  		//err = cferr.Wrap(cferr.CSRError, cferr.ParseFailed, err)
   131  		return
   132  	}
   133  	err = csrv.CheckSignature()
   134  	// if err != nil {
   135  	// 	//err = cferr.Wrap(cferr.CSRError, cferr.KeyMismatch, err)
   136  	// 	return
   137  	// }
   138  	template = &sm2.Certificate{
   139  		Subject:            csrv.Subject,
   140  		PublicKeyAlgorithm: csrv.PublicKeyAlgorithm,
   141  		PublicKey:          csrv.PublicKey,
   142  		SignatureAlgorithm: csrv.SignatureAlgorithm,
   143  		DNSNames:           csrv.DNSNames,
   144  		IPAddresses:        csrv.IPAddresses,
   145  		EmailAddresses:     csrv.EmailAddresses,
   146  	}
   147  
   148  	fmt.Printf("^^^^^^^^^^^^^^^^^^^^^^^^^^algorithn = %v, %v\n", template.PublicKeyAlgorithm, template.SignatureAlgorithm)
   149  	log.Infof("xxxx publicKey :%T", template.PublicKey)
   150  
   151  	template.NotBefore = time.Now()
   152  	template.NotAfter = time.Now().Add(time.Hour * 1000)
   153  	//log.Infof("-----------csrv = %+v", csrv)
   154  	for _, val := range csrv.Extensions {
   155  		// Check the CSR for the X.509 BasicConstraints (RFC 5280, 4.2.1.9)
   156  		// extension and append to template if necessary
   157  		if val.Id.Equal(asn1.ObjectIdentifier{2, 5, 29, 19}) {
   158  			var constraints csr.BasicConstraints
   159  			var rest []byte
   160  
   161  			if rest, err = asn1.Unmarshal(val.Value, &constraints); err != nil {
   162  				//return nil, cferr.Wrap(cferr.CSRError, cferr.ParseFailed, err)
   163  			} else if len(rest) != 0 {
   164  				//return nil, cferr.Wrap(cferr.CSRError, cferr.ParseFailed, errors.New("x509: trailing data after X.509 BasicConstraints"))
   165  			}
   166  
   167  			template.BasicConstraintsValid = true
   168  			template.IsCA = constraints.IsCA
   169  			template.MaxPathLen = constraints.MaxPathLen
   170  			template.MaxPathLenZero = template.MaxPathLen == 0
   171  		}
   172  	}
   173  	serialNumber := make([]byte, 20)
   174  	_, err = io.ReadFull(rand.Reader, serialNumber)
   175  	if err != nil {
   176  		return nil, err
   177  	}
   178  
   179  	// SetBytes interprets buf as the bytes of a big-endian
   180  	// unsigned integer. The leading byte should be masked
   181  	// off to ensure it isn't negative.
   182  	serialNumber[0] &= 0x7F
   183  
   184  	template.SerialNumber = new(big.Int).SetBytes(serialNumber)
   185  
   186  	return
   187  }
   188  
   189  //cloudflare 证书请求 转成 国密证书请求
   190  func generate(priv crypto.Signer, req *csr.CertificateRequest, key bccsp.Key) (csr []byte, err error) {
   191  	log.Info("xx entry gm generate")
   192  	sigAlgo := signerAlgo(priv)
   193  	if sigAlgo == sm2.UnknownSignatureAlgorithm {
   194  		return nil, fmt.Errorf("Private key is unavailable")
   195  	}
   196  	log.Info("xx begin create sm2.CertificateRequest")
   197  	var tpl = sm2.CertificateRequest{
   198  		Subject:            req.Name(),
   199  		SignatureAlgorithm: sigAlgo,
   200  	}
   201  	for i := range req.Hosts {
   202  		if ip := net.ParseIP(req.Hosts[i]); ip != nil {
   203  			tpl.IPAddresses = append(tpl.IPAddresses, ip)
   204  		} else if email, err := mail.ParseAddress(req.Hosts[i]); err == nil && email != nil {
   205  			tpl.EmailAddresses = append(tpl.EmailAddresses, email.Address)
   206  		} else {
   207  			tpl.DNSNames = append(tpl.DNSNames, req.Hosts[i])
   208  		}
   209  	}
   210  
   211  	if req.CA != nil {
   212  		err = appendCAInfoToCSRSm2(req.CA, &tpl)
   213  		if err != nil {
   214  			err = fmt.Errorf("sm2 GenerationFailed")
   215  			return
   216  		}
   217  	}
   218  	if req.SerialNumber != "" {
   219  
   220  	}
   221  	csr, err = gm.CreateSm2CertificateRequestToMem(&tpl, key)
   222  	log.Info("xx exit generate")
   223  	return csr, err
   224  }
   225  
   226  func signerAlgo(priv crypto.Signer) sm2.SignatureAlgorithm {
   227  	switch pub := priv.Public().(type) {
   228  	case *sm2.PublicKey:
   229  		switch pub.Curve {
   230  		case sm2.P256Sm2():
   231  			return sm2.SM2WithSM3
   232  		default:
   233  			return sm2.SM2WithSM3
   234  		}
   235  	default:
   236  		return sm2.UnknownSignatureAlgorithm
   237  	}
   238  }
   239  
   240  // appendCAInfoToCSR appends CAConfig BasicConstraint extension to a CSR
   241  func appendCAInfoToCSR(reqConf *csr.CAConfig, csreq *x509.CertificateRequest) error {
   242  	pathlen := reqConf.PathLength
   243  	if pathlen == 0 && !reqConf.PathLenZero {
   244  		pathlen = -1
   245  	}
   246  	val, err := asn1.Marshal(csr.BasicConstraints{true, pathlen})
   247  
   248  	if err != nil {
   249  		return err
   250  	}
   251  
   252  	csreq.ExtraExtensions = []pkix.Extension{
   253  		{
   254  			Id:       asn1.ObjectIdentifier{2, 5, 29, 19},
   255  			Value:    val,
   256  			Critical: true,
   257  		},
   258  	}
   259  	return nil
   260  }
   261  
   262  // appendCAInfoToCSR appends CAConfig BasicConstraint extension to a CSR
   263  func appendCAInfoToCSRSm2(reqConf *csr.CAConfig, csreq *sm2.CertificateRequest) error {
   264  	pathlen := reqConf.PathLength
   265  	if pathlen == 0 && !reqConf.PathLenZero {
   266  		pathlen = -1
   267  	}
   268  	val, err := asn1.Marshal(csr.BasicConstraints{true, pathlen})
   269  
   270  	if err != nil {
   271  		return err
   272  	}
   273  
   274  	csreq.ExtraExtensions = []pkix.Extension{
   275  		{
   276  			Id:       asn1.ObjectIdentifier{2, 5, 29, 19},
   277  			Value:    val,
   278  			Critical: true,
   279  		},
   280  	}
   281  
   282  	return nil
   283  }
   284  
   285  func ParseX509Certificate2Sm2(x509Cert *x509.Certificate) *sm2.Certificate {
   286  	sm2cert := &sm2.Certificate{
   287  		Raw:                         x509Cert.Raw,
   288  		RawTBSCertificate:           x509Cert.RawTBSCertificate,
   289  		RawSubjectPublicKeyInfo:     x509Cert.RawSubjectPublicKeyInfo,
   290  		RawSubject:                  x509Cert.RawSubject,
   291  		RawIssuer:                   x509Cert.RawIssuer,
   292  		Signature:                   x509Cert.Signature,
   293  		SignatureAlgorithm:          sm2.SignatureAlgorithm(x509Cert.SignatureAlgorithm),
   294  		PublicKeyAlgorithm:          sm2.PublicKeyAlgorithm(x509Cert.PublicKeyAlgorithm),
   295  		PublicKey:                   x509Cert.PublicKey,
   296  		Version:                     x509Cert.Version,
   297  		SerialNumber:                x509Cert.SerialNumber,
   298  		Issuer:                      x509Cert.Issuer,
   299  		Subject:                     x509Cert.Subject,
   300  		NotBefore:                   x509Cert.NotBefore,
   301  		NotAfter:                    x509Cert.NotAfter,
   302  		KeyUsage:                    sm2.KeyUsage(x509Cert.KeyUsage),
   303  		Extensions:                  x509Cert.Extensions,
   304  		ExtraExtensions:             x509Cert.ExtraExtensions,
   305  		UnhandledCriticalExtensions: x509Cert.UnhandledCriticalExtensions,
   306  		//ExtKeyUsage:	[]x509.ExtKeyUsage(x509Cert.ExtKeyUsage) ,
   307  		UnknownExtKeyUsage:    x509Cert.UnknownExtKeyUsage,
   308  		BasicConstraintsValid: x509Cert.BasicConstraintsValid,
   309  		IsCA:                  x509Cert.IsCA,
   310  		MaxPathLen:            x509Cert.MaxPathLen,
   311  		// MaxPathLenZero indicates that BasicConstraintsValid==true and
   312  		// MaxPathLen==0 should be interpreted as an actual maximum path length
   313  		// of zero. Otherwise, that combination is interpreted as MaxPathLen
   314  		// not being set.
   315  		MaxPathLenZero: x509Cert.MaxPathLenZero,
   316  		SubjectKeyId:   x509Cert.SubjectKeyId,
   317  		AuthorityKeyId: x509Cert.AuthorityKeyId,
   318  		// RFC 5280, 4.2.2.1 (Authority Information Access)
   319  		OCSPServer:            x509Cert.OCSPServer,
   320  		IssuingCertificateURL: x509Cert.IssuingCertificateURL,
   321  		// Subject Alternate Name values
   322  		DNSNames:       x509Cert.DNSNames,
   323  		EmailAddresses: x509Cert.EmailAddresses,
   324  		IPAddresses:    x509Cert.IPAddresses,
   325  		// Name constraints
   326  		PermittedDNSDomainsCritical: x509Cert.PermittedDNSDomainsCritical,
   327  		PermittedDNSDomains:         x509Cert.PermittedDNSDomains,
   328  		// CRL Distribution Points
   329  		CRLDistributionPoints: x509Cert.CRLDistributionPoints,
   330  		PolicyIdentifiers:     x509Cert.PolicyIdentifiers,
   331  	}
   332  	for _, val := range x509Cert.ExtKeyUsage {
   333  		sm2cert.ExtKeyUsage = append(sm2cert.ExtKeyUsage, sm2.ExtKeyUsage(val))
   334  	}
   335  	return sm2cert
   336  }