// 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 := primitives.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{Cert: &pb.Cert{Cert: raw}, RootCert: &pb.Cert{Cert: tlscap.tlsca.raw}}, nil }
func TestReadUserSetNonAuditor(t *testing.T) { ecaa := &ECAA{eca} req := &pb.ReadUserSetReq{ Req: &pb.Identity{Id: testUser.enrollID}, Role: 1, Sig: nil} //sign the req hash := primitives.NewHash() raw, _ := proto.Marshal(req) hash.Write(raw) r, s, err := ecdsa.Sign(rand.Reader, testUser.enrollPrivKey, hash.Sum(nil)) if err != nil { t.Fatalf("Failed (ECDSA) signing [%s]", err.Error()) } R, _ := r.MarshalText() S, _ := s.MarshalText() req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} _, err = ecaa.ReadUserSet(context.Background(), req) if err == nil { t.Fatal("Only auditors should be able to call ReadUserSet") } }
// 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 := primitives.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 []*pb.TCert var kdfKey []byte for rows.Next() { var raw []byte if err = rows.Scan(&raw, &kdfKey); err != nil { return nil, err } // TODO: TCert must include attribute keys, we need to save them in the db when generating the batch of TCerts certs = append(certs, &pb.TCert{raw, make(map[string][]byte)}) } if err = rows.Err(); err != nil { return nil, err } return &pb.CertSet{in.Ts, in.Id, kdfKey, certs}, nil }
func (ca *CA) persistCertificate(id string, timestamp int64, usage x509.KeyUsage, certRaw []byte, kdfKey []byte) error { hash := primitives.NewHash() hash.Write(certRaw) var err error if _, err = ca.db.Exec("INSERT INTO Certificates (id, timestamp, usage, cert, hash, kdfkey) VALUES (?, ?, ?, ?, ?, ?)", id, timestamp, usage, certRaw, hash.Sum(nil), kdfKey); err != nil { Error.Println(err) } return err }
// 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 := primitives.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 verification failed.") } 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: id}, pb.Role(role)}) } err = rows.Err() } return &pb.UserSet{users}, err }
func (ecaa *ECAA) checkRegistrarSignature(in *pb.RegisterUserReq) error { Trace.Println("ECAA.checkRegistrarSignature") // If no registrar was specified if in.Registrar == nil || in.Registrar.Id == nil || in.Registrar.Id.Id == "" { Trace.Println("gRPC ECAA:checkRegistrarSignature: no registrar was specified") return errors.New("no registrar was specified") } // Get the raw cert for the registrar registrar := in.Registrar.Id.Id raw, err := ecaa.eca.readCertificateByKeyUsage(registrar, x509.KeyUsageDigitalSignature) if err != nil { return err } // Parse the cert cert, err := x509.ParseCertificate(raw) if err != nil { return err } // Remove the signature sig := in.Sig in.Sig = nil // Marshall the raw bytes r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) hash := primitives.NewHash() raw, _ = proto.Marshal(in) hash.Write(raw) // Check the signature if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { // Signature verification failure Trace.Printf("ECAA.checkRegistrarSignature: failure for %s\n", registrar) return errors.New("Signature verification failed.") } // Signature verification was successful Trace.Printf("ECAA.checkRegistrarSignature: success for %s\n", registrar) return nil }
func (ca *CA) createCertificateFromSpec(spec *CertificateSpec, timestamp int64, kdfKey []byte) ([]byte, error) { Trace.Println("Creating certificate for " + spec.GetId() + ".") raw, err := ca.newCertificateFromSpec(spec) if err != nil { Error.Println(err) return nil, err } hash := primitives.NewHash() hash.Write(raw) if _, err = ca.db.Exec("INSERT INTO Certificates (id, timestamp, usage, cert, hash, kdfkey) VALUES (?, ?, ?, ?, ?, ?)", spec.GetId(), timestamp, spec.GetUsage(), raw, hash.Sum(nil), kdfKey); err != nil { Error.Println(err) } return raw, err }
// FetchAttributes fetchs the attributes from the outside world and populate them into the database. func (acap *ACAP) FetchAttributes(ctx context.Context, in *pb.ACAFetchAttrReq) (*pb.ACAFetchAttrResp, error) { Trace.Println("grpc ACAP:FetchAttributes") if in.Ts == nil || in.ECert == nil || in.Signature == nil { return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE, Msg: "Bad request"}, nil } cert, err := acap.aca.getECACertificate() if err != nil { return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, errors.New("Error getting ECA certificate.") } ecaPub := cert.PublicKey.(*ecdsa.PublicKey) r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(in.Signature.R) s.UnmarshalText(in.Signature.S) in.Signature = nil hash := primitives.NewHash() raw, _ := proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(ecaPub, hash.Sum(nil), r, s) == false { return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE, Msg: "Signature does not verify"}, nil } cert, err = x509.ParseCertificate(in.ECert.Cert) if err != nil { return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, err } var id, affiliation string id, _, affiliation, err = acap.aca.parseEnrollID(cert.Subject.CommonName) if err != nil { return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, err } err = acap.aca.fetchAndPopulateAttributes(id, affiliation) if err != nil { return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, err } return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_SUCCESS}, nil }
func registerUser(registrar User, user *User) error { ecaa := &ECAA{eca} //create req req := &pb.RegisterUserReq{ Id: &pb.Identity{Id: user.enrollID}, Role: pb.Role(user.role), Account: user.affiliation, Affiliation: user.affiliationRole, Registrar: &pb.Registrar{ Id: &pb.Identity{Id: registrar.enrollID}, Roles: user.registrarRoles, DelegateRoles: user.registrarDelegateRoles, }, Sig: nil} //sign the req hash := primitives.NewHash() raw, _ := proto.Marshal(req) hash.Write(raw) r, s, err := ecdsa.Sign(rand.Reader, registrar.enrollPrivKey, hash.Sum(nil)) if err != nil { msg := "Failed to register user. Error (ECDSA) signing request: " + err.Error() return errors.New(msg) } R, _ := r.MarshalText() S, _ := s.MarshalText() req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} token, err := ecaa.RegisterUser(context.Background(), req) if err != nil { return err } if token == nil { return errors.New("Failed to obtain token") } //need the token for later tests user.enrollPwd = token.Tok return nil }
// 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 := primitives.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 }
func TestReadUserSet(t *testing.T) { //enroll Auditor err := enrollUser(&testAuditor) if err != nil { t.Errorf("Failed to read user set: [%s]", err.Error()) } ecaa := &ECAA{eca} req := &pb.ReadUserSetReq{ Req: &pb.Identity{Id: testAuditor.enrollID}, Role: 1, Sig: nil} //sign the req hash := primitives.NewHash() raw, _ := proto.Marshal(req) hash.Write(raw) r, s, err := ecdsa.Sign(rand.Reader, testAuditor.enrollPrivKey, hash.Sum(nil)) if err != nil { t.Errorf("Failed signing [%s].", err.Error()) } R, _ := r.MarshalText() S, _ := s.MarshalText() req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} resp, err := ecaa.ReadUserSet(context.Background(), req) if err != nil { t.Errorf("Failed to read user set: [%s]", err.Error()) } t.Logf("number of users: [%d]", len(resp.Users)) }
func TestReadCertificateByHash(t *testing.T) { ecap := &ECAP{eca} req := &pb.ECertReadReq{Id: &pb.Identity{Id: testUser.enrollID}} cert, err := ecap.ReadCertificatePair(context.Background(), req) if err != nil { t.Fatalf("Failed to read certificate pair: [%s]", err.Error()) } hash := primitives.NewHash() raw, _ := proto.Marshal(cert) hash.Write(raw) hashReq := &pb.Hash{Hash: hash.Sum(nil)} certByHash, _ := ecap.ReadCertificateByHash(context.Background(), hashReq) if certByHash == nil { t.Error("A. ") } }
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 := primitives.NewECDSAKey() if err != nil { node.Errorf("Failed generating ECDSA key [%s].", err.Error()) return nil, nil, nil, err } signPub, err := x509.MarshalPKIXPublicKey(&signPriv.PublicKey) if err != nil { node.Errorf("Failed mashalling ECDSA key [%s].", err.Error()) return nil, nil, nil, err } encPriv, err := primitives.NewECDSAKey() if err != nil { node.Errorf("Failed generating Encryption key [%s].", err.Error()) return nil, nil, nil, err } encPub, err := x509.MarshalPKIXPublicKey(&encPriv.PublicKey) if err != nil { node.Errorf("Failed marshalling Encryption key [%s].", err.Error()) return nil, nil, nil, err } req := &membersrvc.ECertCreateReq{ Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, Id: &membersrvc.Identity{Id: id}, Tok: &membersrvc.Token{Tok: []byte(pw)}, Sign: &membersrvc.PublicKey{Type: membersrvc.CryptoType_ECDSA, Key: signPub}, Enc: &membersrvc.PublicKey{Type: membersrvc.CryptoType_ECDSA, Key: encPub}, Sig: nil} resp, err := ecaP.CreateCertificatePair(context.Background(), req) if err != nil { node.Errorf("Failed invoking CreateCertficatePair [%s].", err.Error()) return nil, nil, nil, err } if resp.FetchResult != nil && resp.FetchResult.Status != membersrvc.FetchAttrsResult_SUCCESS { node.Warning(resp.FetchResult.Msg) } //out, err := rsa.DecryptPKCS1v15(rand.Reader, encPriv, resp.Tok.Tok) spi := ecies.NewSPI() eciesKey, err := spi.NewPrivateKey(nil, encPriv) if err != nil { node.Errorf("Failed parsing decrypting key [%s].", err.Error()) return nil, nil, nil, err } ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey) if err != nil { node.Errorf("Failed creating asymmetrinc cipher [%s].", err.Error()) return nil, nil, nil, err } out, err := ecies.Process(resp.Tok.Tok) if err != nil { node.Errorf("Failed decrypting toke [%s].", err.Error()) return nil, nil, nil, err } req.Tok.Tok = out req.Sig = nil hash := primitives.NewHash() raw, _ := proto.Marshal(req) hash.Write(raw) r, s, err := ecdsa.Sign(rand.Reader, signPriv, hash.Sum(nil)) if err != nil { node.Errorf("Failed signing [%s].", err.Error()) return nil, nil, nil, err } R, _ := r.MarshalText() S, _ := s.MarshalText() req.Sig = &membersrvc.Signature{Type: membersrvc.CryptoType_ECDSA, R: R, S: S} resp, err = ecaP.CreateCertificatePair(context.Background(), req) if err != nil { node.Errorf("Failed invoking CreateCertificatePair [%s].", err.Error()) return nil, nil, nil, err } // Verify response // Verify cert for signing node.Debugf("Enrollment certificate for signing [% x]", primitives.Hash(resp.Certs.Sign)) x509SignCert, err := primitives.DERToX509Certificate(resp.Certs.Sign) if err != nil { node.Errorf("Failed parsing signing enrollment certificate for signing: [%s]", err) return nil, nil, nil, err } _, err = primitives.GetCriticalExtension(x509SignCert, ECertSubjectRole) if err != nil { node.Errorf("Failed parsing ECertSubjectRole in enrollment certificate for signing: [%s]", err) return nil, nil, nil, err } err = primitives.CheckCertAgainstSKAndRoot(x509SignCert, signPriv, node.ecaCertPool) if err != nil { node.Errorf("Failed checking signing enrollment certificate for signing: [%s]", err) return nil, nil, nil, err } // Verify cert for encrypting node.Debugf("Enrollment certificate for encrypting [% x]", primitives.Hash(resp.Certs.Enc)) x509EncCert, err := primitives.DERToX509Certificate(resp.Certs.Enc) if err != nil { node.Errorf("Failed parsing signing enrollment certificate for encrypting: [%s]", err) return nil, nil, nil, err } _, err = primitives.GetCriticalExtension(x509EncCert, ECertSubjectRole) if err != nil { node.Errorf("Failed parsing ECertSubjectRole in enrollment certificate for encrypting: [%s]", err) return nil, nil, nil, err } err = primitives.CheckCertAgainstSKAndRoot(x509EncCert, encPriv, node.ecaCertPool) if err != nil { node.Errorf("Failed checking signing enrollment certificate for encrypting: [%s]", err) return nil, nil, nil, err } return signPriv, resp.Certs.Sign, resp.Pkchain, 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 := primitives.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 []*pb.TCert 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 } // TODO: TCert must include attribute keys, we need to save them in the db when generating the batch of TCerts certs = append(certs, &pb.TCert{cert, make(map[string][]byte)}) } 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 }
// RequestAttributes lookups the atributes in the database and return a certificate with attributes included in the request and found in the database. func (acap *ACAP) RequestAttributes(ctx context.Context, in *pb.ACAAttrReq) (*pb.ACAAttrResp, error) { Trace.Println("grpc ACAP:RequestAttributes") fail := pb.ACAAttrResp_FULL_SUCCESSFUL // else explicit which-param-failed error if nil == in.Ts { fail = pb.ACAAttrResp_FAIL_NIL_TS } else if nil == in.Id { fail = pb.ACAAttrResp_FAIL_NIL_ID } else if nil == in.ECert { fail = pb.ACAAttrResp_FAIL_NIL_ECERT } else if nil == in.Signature { fail = pb.ACAAttrResp_FAIL_NIL_SIGNATURE } if pb.ACAAttrResp_FULL_SUCCESSFUL != fail { return acap.createRequestAttributeResponse(fail, nil), nil } if in.Attributes == nil { in.Attributes = []*pb.TCertAttribute{} } attrs := make(map[string]bool) for _, attrPair := range in.Attributes { if attrs[attrPair.AttributeName] { return acap.createRequestAttributeResponse(pb.ACAAttrResp_BAD_REQUEST, nil), nil } attrs[attrPair.AttributeName] = true } cert, err := acap.aca.getTCACertificate() if err != nil { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), errors.New("Error getting TCA certificate.") } tcaPub := cert.PublicKey.(*ecdsa.PublicKey) r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(in.Signature.R) s.UnmarshalText(in.Signature.S) in.Signature = nil hash := primitives.NewHash() raw, _ := proto.Marshal(in) hash.Write(raw) if ecdsa.Verify(tcaPub, hash.Sum(nil), r, s) == false { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), errors.New("Signature does not verify") } cert, err = x509.ParseCertificate(in.ECert.Cert) if err != nil { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err } var id, affiliation string id, _, affiliation, err = acap.aca.parseEnrollID(cert.Subject.CommonName) if err != nil { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err } //Before continue with the request we perform a refresh of the attributes. err = acap.aca.fetchAndPopulateAttributes(id, affiliation) if err != nil { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err } var verifyCounter int var attributes = make([]AttributePair, 0) owner := &AttributeOwner{id, affiliation} for _, attrPair := range in.Attributes { verifiedPair, _ := acap.aca.findAttribute(owner, attrPair.AttributeName) if verifiedPair != nil { verifyCounter++ attributes = append(attributes, *verifiedPair) } } var extensions = make([]pkix.Extension, 0) extensions, err = acap.addAttributesToExtensions(&attributes, extensions) if err != nil { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err } spec := NewDefaultCertificateSpec(id, cert.PublicKey, cert.KeyUsage, extensions...) raw, err = acap.aca.newCertificateFromSpec(spec) if err != nil { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err } if verifyCounter == 0 { return acap.createRequestAttributeResponse(pb.ACAAttrResp_NO_ATTRIBUTES_FOUND, &pb.Cert{Cert: raw}), nil } count := len(in.Attributes) if count == verifyCounter { return acap.createRequestAttributeResponse(pb.ACAAttrResp_FULL_SUCCESSFUL, &pb.Cert{Cert: raw}), nil } return acap.createRequestAttributeResponse(pb.ACAAttrResp_PARTIAL_SUCCESSFUL, &pb.Cert{Cert: raw}), nil }
func (tcap *TCAP) createCertificateSet(ctx context.Context, raw []byte, in *pb.TCertCreateSetReq) (*pb.TCertCreateSetResp, error) { var attrs = []*pb.ACAAttribute{} var err error var id = in.Id.Id var timestamp = in.Ts.Seconds const TCERT_SUBJECT_COMMON_NAME_VALUE string = "Transaction Certificate" if in.Attributes != nil && viper.GetBool("aca.enabled") { attrs, err = tcap.requestAttributes(id, raw, in.Attributes) if err != nil { return nil, err } } cert, err := x509.ParseCertificate(raw) if err != nil { return nil, err } pub := cert.PublicKey.(*ecdsa.PublicKey) r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(in.Sig.R) s.UnmarshalText(in.Sig.S) //sig := in.Sig in.Sig = nil hash := primitives.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") } // Generate nonce for TCertIndex 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(primitives.GetDefaultHash(), tcap.tca.hmacKey) raw, _ = x509.MarshalPKIXPublicKey(pub) mac.Write(raw) kdfKey := mac.Sum(nil) num := int(in.Num) if num == 0 { num = 1 } // the batch of TCerts var set []*pb.TCert for i := 0; i < num; i++ { tcertid := util.GenerateIntUUID() // Compute TCertIndex tidx := []byte(strconv.Itoa(2*i + 1)) tidx = append(tidx[:], nonce[:]...) tidx = append(tidx[:], Padding...) mac := hmac.New(primitives.GetDefaultHash(), kdfKey) mac.Write([]byte{1}) extKey := mac.Sum(nil)[:32] mac = hmac.New(primitives.GetDefaultHash(), kdfKey) mac.Write([]byte{2}) mac = hmac.New(primitives.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} // Compute encrypted TCertIndex encryptedTidx, err := primitives.CBCPKCS7Encrypt(extKey, tidx) if err != nil { return nil, err } extensions, preK0, err := tcap.generateExtensions(tcertid, encryptedTidx, cert, attrs) if err != nil { return nil, err } spec := NewDefaultPeriodCertificateSpecWithCommonName(id, TCERT_SUBJECT_COMMON_NAME_VALUE, tcertid, &txPub, x509.KeyUsageDigitalSignature, extensions...) if raw, err = tcap.tca.createCertificateFromSpec(spec, timestamp, kdfKey, false); err != nil { Error.Println(err) return nil, err } set = append(set, &pb.TCert{Cert: raw, Prek0: preK0}) } tcap.tca.persistCertificateSet(id, timestamp, nonce, kdfKey) return &pb.TCertCreateSetResp{Certs: &pb.CertSet{Ts: in.Ts, Id: in.Id, Key: kdfKey, Certs: set}}, 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) r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(in.Sig.R) s.UnmarshalText(in.Sig.S) //sig := in.Sig in.Sig = nil hash := primitives.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") } // Generate nonce for TCertIndex nonce := make([]byte, 16) // 8 bytes rand, 8 bytes timestamp rand.Reader.Read(nonce[:8]) mac := hmac.New(primitives.GetDefaultHash(), tcap.tca.hmacKey) raw, _ = x509.MarshalPKIXPublicKey(pub) mac.Write(raw) kdfKey := mac.Sum(nil) num := int(in.Num) if num == 0 { num = 1 } // the batch of TCerts var set []*pb.TCert for i := 0; i < num; i++ { tcertid := util.GenerateIntUUID() // Compute TCertIndex tidx := []byte(strconv.Itoa(2*i + 1)) tidx = append(tidx[:], nonce[:]...) tidx = append(tidx[:], Padding...) mac := hmac.New(primitives.GetDefaultHash(), kdfKey) mac.Write([]byte{1}) extKey := mac.Sum(nil)[:32] mac = hmac.New(primitives.GetDefaultHash(), kdfKey) mac.Write([]byte{2}) mac = hmac.New(primitives.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} // Compute encrypted TCertIndex encryptedTidx, err := CBCEncrypt(extKey, tidx) if err != nil { return nil, err } // TODO: We are storing each K used on the TCert in the ks array (the second return value of this call), but not returning it to the user. // We need to design a structure to return each TCert and the associated Ks. extensions, ks, err := tcap.generateExtensions(tcertid, encryptedTidx, cert, in.Attributes) if err != nil { return nil, err } spec := NewDefaultPeriodCertificateSpec(id, tcertid, &txPub, x509.KeyUsageDigitalSignature, extensions...) if raw, err = tcap.tca.createCertificateFromSpec(spec, in.Ts.Seconds, kdfKey); err != nil { Error.Println(err) return nil, err } set = append(set, &pb.TCert{raw, ks}) } return &pb.TCertCreateSetResp{&pb.CertSet{in.Ts, in.Id, kdfKey, set}}, nil }
//helper function for multiple tests func enrollUser(user *User) error { ecap := &ECAP{eca} // Phase 1 of the protocol: Generate crypto material signPriv, err := primitives.NewECDSAKey() user.enrollPrivKey = signPriv if err != nil { return err } signPub, err := x509.MarshalPKIXPublicKey(&signPriv.PublicKey) if err != nil { return err } encPriv, err := primitives.NewECDSAKey() if err != nil { return err } encPub, err := x509.MarshalPKIXPublicKey(&encPriv.PublicKey) if err != nil { return err } req := &pb.ECertCreateReq{ Ts: &google_protobuf.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, Id: &pb.Identity{Id: user.enrollID}, Tok: &pb.Token{Tok: user.enrollPwd}, Sign: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: signPub}, Enc: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: encPub}, Sig: nil} resp, err := ecap.CreateCertificatePair(context.Background(), req) if err != nil { return err } //Phase 2 of the protocol spi := ecies.NewSPI() eciesKey, err := spi.NewPrivateKey(nil, encPriv) if err != nil { return err } ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey) if err != nil { return err } out, err := ecies.Process(resp.Tok.Tok) if err != nil { return err } req.Tok.Tok = out req.Sig = nil hash := primitives.NewHash() raw, _ := proto.Marshal(req) hash.Write(raw) r, s, err := ecdsa.Sign(rand.Reader, signPriv, hash.Sum(nil)) if err != nil { return err } R, _ := r.MarshalText() S, _ := s.MarshalText() req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} resp, err = ecap.CreateCertificatePair(context.Background(), req) if err != nil { return err } // Verify we got valid crypto material back x509SignCert, err := primitives.DERToX509Certificate(resp.Certs.Sign) if err != nil { return err } _, err = primitives.GetCriticalExtension(x509SignCert, ECertSubjectRole) if err != nil { return err } x509EncCert, err := primitives.DERToX509Certificate(resp.Certs.Enc) if err != nil { return err } _, err = primitives.GetCriticalExtension(x509EncCert, ECertSubjectRole) if err != nil { return err } return 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 var enrollID string id := in.Id.Id err := ecap.eca.readUser(id).Scan(&role, &tok, &state, &prev, &enrollID) if err != nil || !bytes.Equal(tok, in.Tok.Tok) { return nil, errors.New("Identity or token does 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 } 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{Certs: nil, Chain: nil, Pkchain: nil, Tok: &pb.Token{Tok: 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 do not 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 (signing) key type.") } skey, err := x509.ParsePKIXPublicKey(in.Sign.Key) if err != nil { return nil, err } hash := primitives.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 verification failed.") } // create new certificate pair ts := time.Now().Add(-1 * time.Minute).UnixNano() spec := NewDefaultCertificateSpecWithCommonName(id, enrollID, skey.(*ecdsa.PublicKey), x509.KeyUsageDigitalSignature, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))}) sraw, err := ecap.eca.createCertificateFromSpec(spec, ts, nil) if err != nil { Error.Println(err) return nil, err } spec = NewDefaultCertificateSpecWithCommonName(id, enrollID, ekey.(*ecdsa.PublicKey), x509.KeyUsageDataEncipherment, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))}) eraw, err := ecap.eca.createCertificateFromSpec(spec, ts, nil) 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) { obcECKey = ecap.eca.obcPriv } else { obcECKey = ecap.eca.obcPub } return &pb.ECertCreateResp{Certs: &pb.CertPair{Sign: sraw, Enc: eraw}, Chain: &pb.Token{Tok: ecap.eca.obcKey}, Pkchain: obcECKey, Tok: nil}, nil } return nil, errors.New("Invalid (=expired) certificate creation token provided.") }