...

Source file src/github.com/tjfoc/gmsm/x509/utils.go

Documentation: github.com/tjfoc/gmsm/x509

     1  package x509
     2  
     3  import (
     4  	"bytes"
     5  	"crypto"
     6  	"crypto/rand"
     7  	"crypto/rsa"
     8  	"crypto/x509"
     9  	"encoding/asn1"
    10  	"encoding/hex"
    11  	"encoding/pem"
    12  	"errors"
    13  	"math/big"
    14  
    15  	"github.com/tjfoc/gmsm/sm2"
    16  )
    17  
    18  func ReadPrivateKeyFromPem(privateKeyPem []byte, pwd []byte) (*sm2.PrivateKey, error) {
    19  	var block *pem.Block
    20  	block, _ = pem.Decode(privateKeyPem)
    21  	if block == nil {
    22  		return nil, errors.New("failed to decode private key")
    23  	}
    24  	priv, err := ParsePKCS8PrivateKey(block.Bytes, pwd)
    25  	return priv, err
    26  }
    27  
    28  func WritePrivateKeyToPem(key *sm2.PrivateKey, pwd []byte) ([]byte, error) {
    29  	var block *pem.Block
    30  	der, err := MarshalSm2PrivateKey(key, pwd) //Convert private key to DER format
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	if pwd != nil {
    35  		block = &pem.Block{
    36  			Type:  "ENCRYPTED PRIVATE KEY",
    37  			Bytes: der,
    38  		}
    39  	} else {
    40  		block = &pem.Block{
    41  			Type:  "PRIVATE KEY",
    42  			Bytes: der,
    43  		}
    44  	}
    45  	certPem := pem.EncodeToMemory(block)
    46  	return certPem, nil
    47  }
    48  
    49  func ReadPublicKeyFromPem(publicKeyPem []byte) (*sm2.PublicKey, error) {
    50  	block, _ := pem.Decode(publicKeyPem)
    51  	if block == nil || block.Type != "PUBLIC KEY" {
    52  		return nil, errors.New("failed to decode public key")
    53  	}
    54  	return ParseSm2PublicKey(block.Bytes)
    55  }
    56  
    57  func WritePublicKeyToPem(key *sm2.PublicKey) ([]byte, error) {
    58  	der, err := MarshalSm2PublicKey(key) //Convert publick key to DER format
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	block := &pem.Block{
    63  		Type:  "PUBLIC KEY",
    64  		Bytes: der,
    65  	}
    66  	certPem := pem.EncodeToMemory(block)
    67  	return certPem, nil
    68  }
    69  
    70  //DHex是sm2私钥的真正关键数值
    71  func ReadPrivateKeyFromHex(Dhex string) (*sm2.PrivateKey,error) {
    72  	c := sm2.P256Sm2()
    73  	d,err:=hex.DecodeString(Dhex)
    74  	if err!=nil{
    75  		return nil,err
    76  	}
    77  	k:= new(big.Int).SetBytes(d)
    78  	params := c.Params()
    79  	one := new(big.Int).SetInt64(1)
    80  	n := new(big.Int).Sub(params.N, one)
    81  	if k.Cmp(n)>=0{
    82        return nil,errors.New("privateKey's D is overflow.")
    83  	}
    84  	priv := new(sm2.PrivateKey)
    85  	priv.PublicKey.Curve = c
    86  	priv.D = k
    87  	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
    88  	return priv,nil
    89  }
    90  
    91  
    92  
    93  func WritePrivateKeyToHex(key *sm2.PrivateKey) string {
    94  	return key.D.Text(16)
    95  }
    96  
    97  func ReadPublicKeyFromHex(Qhex string) (*sm2.PublicKey, error) {
    98  	q,err:=hex.DecodeString(Qhex)
    99  	if err!=nil{
   100  		return nil,err
   101  	}
   102  	if len(q)==65&&q[0]==byte(0x04){
   103  		q=q[1:]
   104  	}
   105  	if len(q)!=64{
   106  		return nil,errors.New("publicKey is not uncompressed.")
   107  	}
   108  	pub := new(sm2.PublicKey)
   109  	pub.Curve = sm2.P256Sm2()
   110  	pub.X = new(big.Int).SetBytes(q[:32])
   111  	pub.Y = new(big.Int).SetBytes(q[32:])
   112  	return pub, nil
   113  }
   114  
   115  
   116  func WritePublicKeyToHex(key *sm2.PublicKey) string {
   117  	x := key.X.Bytes()
   118  	y := key.Y.Bytes()
   119  	if n := len(x); n < 32 {
   120  		x = append(zeroByteSlice()[:32-n], x...)
   121  	}
   122  	if n := len(y); n < 32 {
   123  		y = append(zeroByteSlice()[:32-n], y...)
   124  	}
   125  	c := []byte{}
   126  	c = append(c, x...)
   127  	c = append(c, y...)
   128  	c = append([]byte{0x04}, c...)
   129  	return hex.EncodeToString(c)
   130  }
   131  
   132  
   133  func ReadCertificateRequestFromPem(certPem []byte) (*CertificateRequest, error) {
   134  	block, _ := pem.Decode(certPem)
   135  	if block == nil {
   136  		return nil, errors.New("failed to decode certificate request")
   137  	}
   138  	return ParseCertificateRequest(block.Bytes)
   139  }
   140  
   141  func CreateCertificateRequestToPem(template *CertificateRequest, signer crypto.Signer) ([]byte, error) {
   142  	der, err := CreateCertificateRequest(rand.Reader, template, signer)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  	block := &pem.Block{
   147  		Type:  "CERTIFICATE REQUEST",
   148  		Bytes: der,
   149  	}
   150  	certPem := pem.EncodeToMemory(block)
   151  	return certPem, nil
   152  }
   153  
   154  func ReadCertificateFromPem(certPem []byte) (*Certificate, error) {
   155  	block, _ := pem.Decode(certPem)
   156  	if block == nil {
   157  		return nil, errors.New("failed to decode certificate request")
   158  	}
   159  	return ParseCertificate(block.Bytes)
   160  }
   161  
   162  // CreateCertificate creates a new certificate based on a template. The
   163  // following members of template are used: SerialNumber, Subject, NotBefore,
   164  // NotAfter, KeyUsage, ExtKeyUsage, UnknownExtKeyUsage, BasicConstraintsValid,
   165  // IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical,
   166  // PermittedDNSDomains, SignatureAlgorithm.
   167  //
   168  // The certificate is signed by parent. If parent is equal to template then the
   169  // certificate is self-signed. The parameter pub is the public key of the
   170  // signee and priv is the private key of the signer.
   171  //
   172  // The returned slice is the certificate in DER encoding.
   173  //
   174  // All keys types that are implemented via crypto.Signer are supported (This
   175  // includes *rsa.PublicKey and *ecdsa.PublicKey.)
   176  func CreateCertificate(template, parent *Certificate, publicKey *sm2.PublicKey, signer crypto.Signer) ([]byte, error) {
   177  	if template.SerialNumber == nil {
   178  		return nil, errors.New("x509: no SerialNumber given")
   179  	}
   180  
   181  	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(signer.Public(), template.SignatureAlgorithm)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  
   186  	publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(publicKey)
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  
   191  	asn1Issuer, err := subjectBytes(parent)
   192  	if err != nil {
   193  		return nil, err
   194  	}
   195  
   196  	asn1Subject, err := subjectBytes(template)
   197  	if err != nil {
   198  		return nil, err
   199  	}
   200  
   201  	if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 {
   202  		template.AuthorityKeyId = parent.SubjectKeyId
   203  	}
   204  
   205  	extensions, err := buildExtensions(template)
   206  	if err != nil {
   207  		return nil, err
   208  	}
   209  	encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
   210  	c := tbsCertificate{
   211  		Version:            2,
   212  		SerialNumber:       template.SerialNumber,
   213  		SignatureAlgorithm: signatureAlgorithm,
   214  		Issuer:             asn1.RawValue{FullBytes: asn1Issuer},
   215  		Validity:           validity{template.NotBefore.UTC(), template.NotAfter.UTC()},
   216  		Subject:            asn1.RawValue{FullBytes: asn1Subject},
   217  		PublicKey:          publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},
   218  		Extensions:         extensions,
   219  	}
   220  
   221  	tbsCertContents, err := asn1.Marshal(c)
   222  	if err != nil {
   223  		return nil, err
   224  	}
   225  
   226  	c.Raw = tbsCertContents
   227  
   228  	digest := tbsCertContents
   229  	switch template.SignatureAlgorithm {
   230  	case SM2WithSM3, SM2WithSHA1, SM2WithSHA256:
   231  		break
   232  	default:
   233  		h := hashFunc.New()
   234  		h.Write(tbsCertContents)
   235  		digest = h.Sum(nil)
   236  	}
   237  
   238  	var signerOpts crypto.SignerOpts
   239  	signerOpts = hashFunc
   240  	if template.SignatureAlgorithm != 0 && template.SignatureAlgorithm.isRSAPSS() {
   241  		signerOpts = &rsa.PSSOptions{
   242  			SaltLength: rsa.PSSSaltLengthEqualsHash,
   243  			Hash:       crypto.Hash(hashFunc),
   244  		}
   245  	}
   246  
   247  	var signature []byte
   248  	signature, err = signer.Sign(rand.Reader, digest, signerOpts)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	return asn1.Marshal(certificate{
   253  		nil,
   254  		c,
   255  		signatureAlgorithm,
   256  		asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
   257  	})
   258  }
   259  
   260  // CreateCertificateToPem creates a new certificate based on a template and
   261  // encodes it to PEM format. It uses CreateCertificate to create certificate
   262  // and returns its PEM format.
   263  func CreateCertificateToPem(template, parent *Certificate, pubKey *sm2.PublicKey, signer crypto.Signer) ([]byte, error) {
   264  	der, err := CreateCertificate(template, parent, pubKey, signer)
   265  	if err != nil {
   266  		return nil, err
   267  	}
   268  	block := &pem.Block{
   269  		Type:  "CERTIFICATE",
   270  		Bytes: der,
   271  	}
   272  	certPem := pem.EncodeToMemory(block)
   273  	return certPem, nil
   274  }
   275  
   276  func ParseSm2CertifateToX509(asn1data []byte) (*x509.Certificate, error) {
   277  	sm2Cert, err := ParseCertificate(asn1data)
   278  	if err != nil {
   279  		return nil, err
   280  	}
   281  	return sm2Cert.ToX509Certificate(), nil
   282  }
   283  // 32byte
   284  func zeroByteSlice() []byte {
   285  	return []byte{
   286  		0, 0, 0, 0,
   287  		0, 0, 0, 0,
   288  		0, 0, 0, 0,
   289  		0, 0, 0, 0,
   290  		0, 0, 0, 0,
   291  		0, 0, 0, 0,
   292  		0, 0, 0, 0,
   293  		0, 0, 0, 0,
   294  	}
   295  }
   296  

View as plain text