// CreateCertificate requests the creation of a new enrollment certificate by the TLSCA. // func (tlscap *TLSCAP) CreateCertificate(ctx context.Context, in *pb.TLSCertCreateReq) (*pb.TLSCertCreateResp, error) { Trace.Println("grpc TLSCAP:CreateCertificate") id := in.Id.Id sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) raw := in.Pub.Key if in.Pub.Type != pb.CryptoType_ECDSA { return nil, errors.New("unsupported key type") } pub, err := x509.ParsePKIXPublicKey(in.Pub.Key) if err != nil { return nil, err } hash := utils.NewHash() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(pub.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } if raw, err = tlscap.tlsca.createCertificate(id, pub.(*ecdsa.PublicKey), x509.KeyUsageDigitalSignature, in.Ts.Seconds, nil); err != nil { Error.Println(err) return nil, err } return &pb.TLSCertCreateResp{&pb.Cert{raw}, &pb.Cert{tlscap.tlsca.raw}}, nil }
// ReadCertificateSet reads a transaction certificate set from the TCA. Not yet implemented. // func (tcap *TCAP) ReadCertificateSet(ctx context.Context, in *pb.TCertReadSetReq) (*pb.CertSet, error) { Trace.Println("grpc TCAP:ReadCertificateSet") req := in.Req.Id id := in.Id.Id if req != id && tcap.tca.eca.readRole(req)&int(pb.Role_AUDITOR) == 0 { return nil, errors.New("access denied") } raw, err := tcap.tca.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := utils.NewHash() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } rows, err := tcap.tca.readCertificates(id, in.Ts.Seconds) if err != nil { return nil, err } defer rows.Close() var certs [][]byte var kdfKey []byte for rows.Next() { var raw []byte if err = rows.Scan(&raw, &kdfKey); err != nil { return nil, err } certs = append(certs, raw) } if err = rows.Err(); err != nil { return nil, err } return &pb.CertSet{in.Ts, in.Id, kdfKey, certs}, nil }
// ReadUserSet returns a list of users matching the parameters set in the read request. // func (ecaa *ECAA) ReadUserSet(ctx context.Context, in *pb.ReadUserSetReq) (*pb.UserSet, error) { Trace.Println("grpc ECAA:ReadUserSet") req := in.Req.Id if ecaa.eca.readRole(req)&int(pb.Role_AUDITOR) == 0 { return nil, errors.New("access denied") } raw, err := ecaa.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := utils.NewHash() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } rows, err := ecaa.eca.readUsers(int(in.Role)) if err != nil { return nil, err } defer rows.Close() var users []*pb.User if err == nil { for rows.Next() { var id string var role int err = rows.Scan(&id, &role) users = append(users, &pb.User{&pb.Identity{id}, pb.Role(role)}) } err = rows.Err() } return &pb.UserSet{users}, err }
func (ca *CA) createCertificate(id string, pub interface{}, usage x509.KeyUsage, timestamp int64, kdfKey []byte, opt ...pkix.Extension) ([]byte, error) { Trace.Println("Creating certificate for " + id + ".") raw, err := ca.newCertificate(id, pub, usage, opt) if err != nil { Error.Println(err) return nil, err } hash := utils.NewHash() hash.Write(raw) if _, err = ca.db.Exec("INSERT INTO Certificates (id, timestamp, usage, cert, hash, kdfkey) VALUES (?, ?, ?, ?, ?, ?)", id, timestamp, usage, raw, hash.Sum(nil), kdfKey); err != nil { Error.Println(err) } return raw, err }
// ReadCertificate reads a transaction certificate from the TCA. // func (tcap *TCAP) ReadCertificate(ctx context.Context, in *pb.TCertReadReq) (*pb.Cert, error) { Trace.Println("grpc TCAP:ReadCertificate") req := in.Req.Id id := in.Id.Id if req != id && tcap.tca.eca.readRole(req)&(int(pb.Role_VALIDATOR)|int(pb.Role_AUDITOR)) == 0 { return nil, errors.New("access denied") } raw, err := tcap.tca.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := utils.NewHash() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } if in.Ts.Seconds != 0 { raw, err = tcap.tca.readCertificate1(id, in.Ts.Seconds) } else { raw, err = tcap.tca.readCertificateByHash(in.Hash.Hash) } if err != nil { return nil, err } return &pb.Cert{raw}, nil }
// CreateCertificatePair requests the creation of a new enrollment certificate pair by the ECA. // func (ecap *ECAP) CreateCertificatePair(ctx context.Context, in *pb.ECertCreateReq) (*pb.ECertCreateResp, error) { Trace.Println("grpc ECAP:CreateCertificate") // validate token 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: // initial request, create encryption challenge 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 } // out, err := rsa.EncryptPKCS1v15(rand.Reader, ekey.(*rsa.PublicKey), tok) 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: // ensure that the same encryption key is signed that has been used for the challenge if subtle.ConstantTimeCompare(in.Enc.Key, prev) != 1 { return nil, errors.New("encryption keys don't match") } // validate request signature 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 := utils.NewHash() 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") } // create new certificate pair ts := time.Now().Add(-1 * time.Minute).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) { //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 (node *nodeImpl) getEnrollmentCertificateFromECA(id, pw string) (interface{}, []byte, []byte, error) { // Get a new ECA Client sock, ecaP, err := node.getECAClient() defer sock.Close() // Run the protocol signPriv, err := utils.NewECDSAKey() if err != nil { node.log.Error("Failed generating ECDSA key [%s].", err.Error()) return nil, nil, nil, err } signPub, err := x509.MarshalPKIXPublicKey(&signPriv.PublicKey) if err != nil { node.log.Error("Failed mashalling ECDSA key [%s].", err.Error()) return nil, nil, nil, err } encPriv, err := utils.NewECDSAKey() if err != nil { node.log.Error("Failed generating Encryption key [%s].", err.Error()) return nil, nil, nil, err } encPub, err := x509.MarshalPKIXPublicKey(&encPriv.PublicKey) if err != nil { node.log.Error("Failed marshalling Encryption key [%s].", err.Error()) return nil, nil, nil, err } req := &obcca.ECertCreateReq{&protobuf.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, &obcca.Identity{id}, &obcca.Token{Tok: []byte(pw)}, &obcca.PublicKey{obcca.CryptoType_ECDSA, signPub}, &obcca.PublicKey{obcca.CryptoType_ECDSA, encPub}, nil} resp, err := ecaP.CreateCertificatePair(context.Background(), req) if err != nil { node.log.Error("Failed invoking CreateCertficatePair [%s].", err.Error()) return nil, nil, nil, err } //out, err := rsa.DecryptPKCS1v15(rand.Reader, encPriv, resp.Tok.Tok) spi := ecies.NewSPI() eciesKey, err := spi.NewPrivateKey(nil, encPriv) if err != nil { node.log.Error("Failed parsing decrypting key [%s].", err.Error()) return nil, nil, nil, err } ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey) if err != nil { node.log.Error("Failed creating asymmetrinc cipher [%s].", err.Error()) return nil, nil, nil, err } out, err := ecies.Process(resp.Tok.Tok) if err != nil { node.log.Error("Failed decrypting toke [%s].", err.Error()) return nil, nil, nil, err } req.Tok.Tok = out req.Sig = nil hash := utils.NewHash() raw, _ := proto.Marshal(req) hash.Write(raw) r, s, err := ecdsa.Sign(rand.Reader, signPriv, hash.Sum(nil)) if err != nil { node.log.Error("Failed signing [%s].", err.Error()) return nil, nil, nil, err } R, _ := r.MarshalText() S, _ := s.MarshalText() req.Sig = &obcca.Signature{obcca.CryptoType_ECDSA, R, S} resp, err = ecaP.CreateCertificatePair(context.Background(), req) if err != nil { node.log.Error("Failed invoking CreateCertificatePair [%s].", err.Error()) return nil, nil, nil, err } // Verify response // Verify cert for signing node.log.Debug("Enrollment certificate for signing [%s]", utils.EncodeBase64(utils.Hash(resp.Certs.Sign))) x509SignCert, err := utils.DERToX509Certificate(resp.Certs.Sign) if err != nil { node.log.Error("Failed parsing signing enrollment certificate for signing: [%s]", err) return nil, nil, nil, err } _, err = utils.GetCriticalExtension(x509SignCert, ECertSubjectRole) if err != nil { node.log.Error("Failed parsing ECertSubjectRole in enrollment certificate for signing: [%s]", err) return nil, nil, nil, err } err = utils.CheckCertAgainstSKAndRoot(x509SignCert, signPriv, node.ecaCertPool) if err != nil { node.log.Error("Failed checking signing enrollment certificate for signing: [%s]", err) return nil, nil, nil, err } // Verify cert for encrypting node.log.Debug("Enrollment certificate for encrypting [%s]", utils.EncodeBase64(utils.Hash(resp.Certs.Enc))) x509EncCert, err := utils.DERToX509Certificate(resp.Certs.Enc) if err != nil { node.log.Error("Failed parsing signing enrollment certificate for encrypting: [%s]", err) return nil, nil, nil, err } _, err = utils.GetCriticalExtension(x509EncCert, ECertSubjectRole) if err != nil { node.log.Error("Failed parsing ECertSubjectRole in enrollment certificate for encrypting: [%s]", err) return nil, nil, nil, err } err = utils.CheckCertAgainstSKAndRoot(x509EncCert, encPriv, node.ecaCertPool) if err != nil { node.log.Error("Failed checking signing enrollment certificate for encrypting: [%s]", err) return nil, nil, nil, err } // END return signPriv, resp.Certs.Sign, resp.Chain.Tok, nil }
// ReadCertificateSets returns all certificates matching the filter criteria of the request. // func (tcaa *TCAA) ReadCertificateSets(ctx context.Context, in *pb.TCertReadSetsReq) (*pb.CertSets, error) { Trace.Println("grpc TCAA:ReadCertificateSets") req := in.Req.Id if tcaa.tca.eca.readRole(req)&int(pb.Role_AUDITOR) == 0 { return nil, errors.New("access denied") } raw, err := tcaa.tca.eca.readCertificate(req, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := utils.NewHash() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } users, err := tcaa.tca.eca.readUsers(int(in.Role)) if err != nil { return nil, err } defer users.Close() begin := int64(0) end := int64(math.MaxInt64) if in.Begin != nil { begin = in.Begin.Seconds } if in.End != nil { end = in.End.Seconds } var sets []*pb.CertSet for users.Next() { var id string var role int if err = users.Scan(&id, &role); err != nil { return nil, err } rows, err := tcaa.tca.eca.readCertificateSets(id, begin, end) if err != nil { return nil, err } defer rows.Close() var certs [][]byte var kdfKey []byte var timestamp int64 timestamp = 0 for rows.Next() { var cert []byte var ts int64 if err = rows.Scan(&cert, &kdfKey, &ts); err != nil { return nil, err } if ts != timestamp { sets = append(sets, &pb.CertSet{&protobuf.Timestamp{Seconds: timestamp, Nanos: 0}, &pb.Identity{id}, kdfKey, certs}) timestamp = ts certs = nil } certs = append(certs, cert) } if err = rows.Err(); err != nil { return nil, err } sets = append(sets, &pb.CertSet{&protobuf.Timestamp{Seconds: timestamp, Nanos: 0}, &pb.Identity{id}, kdfKey, certs}) } if err = users.Err(); err != nil { return nil, err } return &pb.CertSets{sets}, nil }
// CreateCertificateSet requests the creation of a new transaction certificate set by the TCA. // func (tcap *TCAP) CreateCertificateSet(ctx context.Context, in *pb.TCertCreateSetReq) (*pb.TCertCreateSetResp, error) { Trace.Println("grpc TCAP:CreateCertificateSet") id := in.Id.Id raw, err := tcap.tca.eca.readCertificate(id, x509.KeyUsageDigitalSignature) if err != nil { return nil, err } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } pub := cert.PublicKey.(*ecdsa.PublicKey) sig := in.Sig in.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := utils.NewHash() raw, _ = proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(pub, hash.Sum(nil), r, s) == false { return nil, errors.New("signature does not verify") } nonce := make([]byte, 16) // 8 bytes rand, 8 bytes timestamp rand.Reader.Read(nonce[:8]) binary.LittleEndian.PutUint64(nonce[8:], uint64(in.Ts.Seconds)) mac := hmac.New(conf.GetDefaultHash(), tcap.tca.hmacKey) raw, _ = x509.MarshalPKIXPublicKey(pub) mac.Write(raw) kdfKey := mac.Sum(nil) num := int(in.Num) if num == 0 { num = 1 } var set [][]byte for i := 0; i < num; i++ { tidx := []byte(strconv.Itoa(i)) tidx = append(tidx[:], nonce[:]...) mac = hmac.New(conf.GetDefaultHash(), kdfKey) mac.Write([]byte{1}) extKey := mac.Sum(nil)[:32] mac = hmac.New(conf.GetDefaultHash(), kdfKey) mac.Write([]byte{2}) mac = hmac.New(conf.GetDefaultHash(), mac.Sum(nil)) mac.Write(tidx) one := new(big.Int).SetInt64(1) k := new(big.Int).SetBytes(mac.Sum(nil)) k.Mod(k, new(big.Int).Sub(pub.Curve.Params().N, one)) k.Add(k, one) tmpX, tmpY := pub.ScalarBaseMult(k.Bytes()) txX, txY := pub.Curve.Add(pub.X, pub.Y, tmpX, tmpY) txPub := ecdsa.PublicKey{Curve: pub.Curve, X: txX, Y: txY} ext, err := CBCEncrypt(extKey, tidx) if err != nil { return nil, err } if raw, err = tcap.tca.createCertificate(id, &txPub, x509.KeyUsageDigitalSignature, in.Ts.Seconds, kdfKey, pkix.Extension{Id: TCertEncTCertIndex, Critical: true, Value: ext}); err != nil { Error.Println(err) return nil, err } set = append(set, raw) } return &pb.TCertCreateSetResp{&pb.CertSet{in.Ts, in.Id, kdfKey, set}}, nil }