github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/gossip/comm/crypto.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package comm 8 9 import ( 10 "crypto/ecdsa" 11 "crypto/elliptic" 12 "crypto/rand" 13 "crypto/tls" 14 "crypto/x509" 15 "encoding/pem" 16 "errors" 17 "fmt" 18 "math/big" 19 "os" 20 21 "github.com/hyperledger/fabric/common/util" 22 gutil "github.com/hyperledger/fabric/gossip/util" 23 "golang.org/x/net/context" 24 "google.golang.org/grpc/credentials" 25 "google.golang.org/grpc/peer" 26 ) 27 28 func writeFile(filename string, keyType string, data []byte) error { 29 f, err := os.Create(filename) 30 if err != nil { 31 return err 32 } 33 defer f.Close() 34 return pem.Encode(f, &pem.Block{Type: keyType, Bytes: data}) 35 } 36 37 func GenerateCertificatesOrPanic() tls.Certificate { 38 privKeyFile := fmt.Sprintf("key.%d.priv", gutil.RandomUInt64()) 39 certKeyFile := fmt.Sprintf("cert.%d.pub", gutil.RandomUInt64()) 40 41 defer os.Remove(privKeyFile) 42 defer os.Remove(certKeyFile) 43 privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 44 if err != nil { 45 panic(err) 46 } 47 48 sn, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) 49 if err != nil { 50 panic(err) 51 } 52 template := x509.Certificate{ 53 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 54 SerialNumber: sn, 55 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 56 } 57 rawBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey) 58 if err != nil { 59 panic(err) 60 } 61 err = writeFile(certKeyFile, "CERTIFICATE", rawBytes) 62 if err != nil { 63 panic(err) 64 } 65 privBytes, err := x509.MarshalECPrivateKey(privateKey) 66 if err != nil { 67 panic(err) 68 } 69 err = writeFile(privKeyFile, "EC PRIVATE KEY", privBytes) 70 if err != nil { 71 panic(err) 72 } 73 cert, err := tls.LoadX509KeyPair(certKeyFile, privKeyFile) 74 if err != nil { 75 panic(err) 76 } 77 if len(cert.Certificate) == 0 { 78 panic(errors.New("Certificate chain is empty")) 79 } 80 return cert 81 } 82 83 func certHashFromRawCert(rawCert []byte) []byte { 84 if len(rawCert) == 0 { 85 return nil 86 } 87 return util.ComputeSHA256(rawCert) 88 } 89 90 // ExtractCertificateHash extracts the hash of the certificate from the stream 91 func extractCertificateHashFromContext(ctx context.Context) []byte { 92 pr, extracted := peer.FromContext(ctx) 93 if !extracted { 94 return nil 95 } 96 97 authInfo := pr.AuthInfo 98 if authInfo == nil { 99 return nil 100 } 101 102 tlsInfo, isTLSConn := authInfo.(credentials.TLSInfo) 103 if !isTLSConn { 104 return nil 105 } 106 certs := tlsInfo.State.PeerCertificates 107 if len(certs) == 0 { 108 return nil 109 } 110 raw := certs[0].Raw 111 return certHashFromRawCert(raw) 112 }