func (ecaa *ECAA) RegisterUser(ctx context.Context, in *pb.RegisterUserReq) (*pb.Token, error) {
	Trace.Println("grpc ECAA:RegisterUser")
	tok, err := ecaa.eca.registerUser(in.Id.Id, int(in.Role))
	return &pb.Token{[]byte(tok)}, err
}
RegisterUser registers a new user with the ECA.  If the user had been registered before
an error is returned.
package obcca
import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/subtle"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"io/ioutil"
	"math/big"
	"strconv"
	"strings"
	"time"
	ecies "github.com/openblockchain/obc-peer/openchain/crypto/ecies/generic"
	"github.com/golang/protobuf/proto"
	pb "github.com/openblockchain/obc-peer/obc-ca/protos"
	"github.com/spf13/viper"
	"golang.org/x/crypto/sha3"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)
var (
	ECertSubjectRole = asn1.ObjectIdentifier{2, 1, 3, 4, 5, 6, 7}
)
type ECA struct {
	*CA
	obcKey          []byte
	obcPriv, obcPub []byte
}
type ECAP struct {
	eca *ECA
}
type ECAA struct {
	eca *ECA
}
func NewECA() *ECA {
	eca := &ECA{NewCA("eca"), nil, nil, nil}
	{
		var cooked string
		raw, err := ioutil.ReadFile(eca.path + "/obc.aes")
		if err != nil {
			rand := rand.Reader
			key := make([]byte, 32)  
			rand.Read(key)
			cooked = base64.StdEncoding.EncodeToString(key)
			err = ioutil.WriteFile(eca.path+"/obc.aes", []byte(cooked), 0644)
			if err != nil {
				Panic.Panicln(err)
			}
		} else {
			cooked = string(raw)
		}
		eca.obcKey, err = base64.StdEncoding.DecodeString(cooked)
		if err != nil {
			Panic.Panicln(err)
		}
	}
	{
		var priv *ecdsa.PrivateKey
		cooked, err := ioutil.ReadFile(eca.path + "/obc.ecies")
		if err == nil {
			block, _ := pem.Decode(cooked)
			priv, err = x509.ParseECPrivateKey(block.Bytes)
			if err != nil {
				Panic.Panicln(err)
			}
		} else {
			priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
			if err != nil {
				Panic.Panicln(err)
			}
			raw, _ := x509.MarshalECPrivateKey(priv)
			cooked = pem.EncodeToMemory(
				&pem.Block{
					Type:  "ECDSA PRIVATE KEY",
					Bytes: raw,
				})
			err := ioutil.WriteFile(eca.path+"/obc.ecies", cooked, 0644)
			if err != nil {
				Panic.Panicln(err)
			}
		}
		eca.obcPriv = cooked
		raw, _ := x509.MarshalPKIXPublicKey(&priv.PublicKey)
		eca.obcPub = pem.EncodeToMemory(
			&pem.Block{
				Type:  "ECDSA PUBLIC KEY",
				Bytes: raw,
			})
	}
	users := viper.GetStringMapString("eca.users")
	for id, flds := range users {
		vals := strings.Fields(flds)
		role, err := strconv.Atoi(vals[0])
		if err != nil {
			Panic.Panicln(err)
		}
		eca.registerUser(id, role, vals[1])
	}
	return eca
}
func (eca *ECA) Start(srv *grpc.Server) {
	eca.startECAP(srv)
	eca.startECAA(srv)
	Info.Println("ECA started.")
}
func (eca *ECA) startECAP(srv *grpc.Server) {
	pb.RegisterECAPServer(srv, &ECAP{eca})
}
func (eca *ECA) startECAA(srv *grpc.Server) {
	pb.RegisterECAAServer(srv, &ECAA{eca})
}
func (ecap *ECAP) ReadCACertificate(ctx context.Context, in *pb.Empty) (*pb.Cert, error) {
	Trace.Println("grpc ECAP:ReadCACertificate")
	return &pb.Cert{ecap.eca.raw}, nil
}
func (ecap *ECAP) CreateCertificatePair(ctx context.Context, in *pb.ECertCreateReq) (*pb.ECertCreateResp, error) {
	Trace.Println("grpc ECAP:CreateCertificate")
	var tok, prev []byte
	var role, state int
	id := in.Id.Id
	err := ecap.eca.readUser(id).Scan(&role, &tok, &state, &prev)
	if err != nil || !bytes.Equal(tok, in.Tok.Tok) {
		return nil, errors.New("identity or token do not match")
	}
	ekey, err := x509.ParsePKIXPublicKey(in.Enc.Key)
	if err != nil {
		return nil, err
	}
	switch {
	case state == 0:
		tok = []byte(randomString(12))
		_, err = ecap.eca.db.Exec("UPDATE Users SET token=?, state=?, key=? WHERE id=?", tok, 1, in.Enc.Key, id)
		if err != nil {
			Error.Println(err)
			return nil, err
		}
		spi := ecies.NewSPI()
		eciesKey, err := spi.NewPublicKey(nil, ekey.(*ecdsa.PublicKey))
		if err != nil {
			return nil, err
		}
		ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey)
		if err != nil {
			return nil, err
		}
		out, err := ecies.Process(tok)
		return &pb.ECertCreateResp{nil, nil, nil, &pb.Token{out}}, err
	case state == 1:
		if subtle.ConstantTimeCompare(in.Enc.Key, prev) != 1 {
			return nil, errors.New("encryption keys don't match")
		}
		sig := in.Sig
		in.Sig = nil
		r, s := big.NewInt(0), big.NewInt(0)
		r.UnmarshalText(sig.R)
		s.UnmarshalText(sig.S)
		if in.Sign.Type != pb.CryptoType_ECDSA {
			return nil, errors.New("unsupported key type")
		}
		skey, err := x509.ParsePKIXPublicKey(in.Sign.Key)
		if err != nil {
			return nil, err
		}
		hash := sha3.New384()
		raw, _ := proto.Marshal(in)
		hash.Write(raw)
		if ecdsa.Verify(skey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false {
			return nil, errors.New("signature does not verify")
		}
		ts := time.Now().UnixNano()
		sraw, err := ecap.eca.createCertificate(id, skey.(*ecdsa.PublicKey), x509.KeyUsageDigitalSignature, ts, nil, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))})
		if err != nil {
			Error.Println(err)
			return nil, err
		}
		eraw, err := ecap.eca.createCertificate(id, ekey.(*ecdsa.PublicKey), x509.KeyUsageDataEncipherment, ts, nil, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))})
		if err != nil {
			ecap.eca.db.Exec("DELETE FROM Certificates Where id=?", id)
			Error.Println(err)
			return nil, err
		}
		_, err = ecap.eca.db.Exec("UPDATE Users SET state=? WHERE id=?", 2, id)
		if err != nil {
			ecap.eca.db.Exec("DELETE FROM Certificates Where id=?", id)
			Error.Println(err)
			return nil, err
		}
		var obcECKey []byte
		if role&(int(pb.Role_VALIDATOR)|int(pb.Role_AUDITOR)) != 0 {
			obcECKey = ecap.eca.obcPriv
		} else {
			obcECKey = ecap.eca.obcPub
		}
		return &pb.ECertCreateResp{&pb.CertPair{sraw, eraw}, &pb.Token{ecap.eca.obcKey}, obcECKey, nil}, nil
	}
	return nil, errors.New("certificate creation token expired")
}
func (ecap *ECAP) ReadCertificatePair(ctx context.Context, in *pb.ECertReadReq) (*pb.CertPair, error) {
	Trace.Println("grpc ECAP:ReadCertificate")
	rows, err := ecap.eca.readCertificates(in.Id.Id)
	defer rows.Close()
	var certs [][]byte
	if err == nil {
		for rows.Next() {
			var raw []byte
			err = rows.Scan(&raw)
			certs = append(certs, raw)
		}
		err = rows.Err()
	}
	return &pb.CertPair{certs[0], certs[1]}, err
}
func (ecap *ECAP) ReadCertificateByHash(ctx context.Context, hash *pb.Hash) (*pb.Cert, error) {
	Trace.Println("grpc ECAP:ReadCertificateByHash")
	raw, err := ecap.eca.readCertificateByHash(hash.Hash)
	return &pb.Cert{raw}, err
}
func (ecap *ECAP) RevokeCertificatePair(context.Context, *pb.ECertRevokeReq) (*pb.CAStatus, error) {
	Trace.Println("grpc ECAP:RevokeCertificate")
	return nil, errors.New("not yet implemented")
}