// CreateCertificate requests the creation of a new enrollment certificate by the ECA. // func (ecap *ECAP) CreateCertificate(ctx context.Context, req *pb.ECertCreateReq) (*pb.Creds, error) { Trace.Println("grpc ECAP:CreateCertificate") id := req.Id.Id if pw, err := ecap.eca.readPassword(id); err != nil || pw != req.Pw.Pw { Error.Println("identity or password do not match") return nil, errors.New("identity or password do not match") } sig := req.Sig req.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) raw := req.Pub.Key if req.Pub.Type != pb.CryptoType_ECDSA { Error.Println("unsupported key type") return nil, errors.New("unsupported key type") } pub, err := x509.ParsePKIXPublicKey(req.Pub.Key) if err != nil { Error.Println(err) return nil, err } hash := sha3.New384() raw, _ = proto.Marshal(req) hash.Write(raw) if ecdsa.Verify(pub.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { Error.Println("signature does not verify") return nil, errors.New("signature does not verify") } raw, err = ecap.eca.readCertificate(id) if err != nil { if raw, err = ecap.eca.newCertificate(id, pub.(*ecdsa.PublicKey), time.Now().UnixNano()); err != nil { Error.Println(err) return nil, err } } return &pb.Creds{&pb.Cert{Cert: raw}, ecap.eca.obcKey}, 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") }
// CreateCertificatePair requests the creation of a new enrollment certificate pair by the ECA. // func (ecap *ECAP) CreateCertificatePair(ctx context.Context, req *pb.ECertCreateReq) (*pb.ECertCreateResp, error) { Trace.Println("grpc ECAP:CreateCertificate") // validate token var tok, prev []byte var state int id := req.Id.Id err := ecap.eca.readToken(id).Scan(&tok, &state, &prev) if err != nil || !bytes.Equal(tok, req.Tok.Tok) { return nil, errors.New("identity or token do not match") } ekey, err := x509.ParsePKIXPublicKey(req.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, req.Enc.Key, id) if err != nil { Error.Println(err) return nil, err } out, err := rsa.EncryptPKCS1v15(rand.Reader, ekey.(*rsa.PublicKey), tok) if err != nil { return nil, err } return &pb.ECertCreateResp{nil, nil, &pb.Token{out}}, nil case state == 1: // ensure that the same encryption key is signed that has been used for the challenge if bytes.Compare(req.Enc.Key, prev) != 0 { return nil, errors.New("encryption keys don't match") } // validate request signature sig := req.Sig req.Sig = nil r, s := big.NewInt(0), big.NewInt(0) r.UnmarshalText(sig.R) s.UnmarshalText(sig.S) if req.Sign.Type != pb.CryptoType_ECDSA { return nil, errors.New("unsupported key type") } skey, err := x509.ParsePKIXPublicKey(req.Sign.Key) if err != nil { return nil, err } hash := sha3.New384() raw, _ := proto.Marshal(req) 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().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.(*rsa.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 } return &pb.ECertCreateResp{&pb.CertPair{sraw, eraw}, &pb.Token{ecap.eca.obcKey}, nil}, nil } return nil, errors.New("certificate creation token expired") }