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 }