Example #1
0
// 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
}
Example #2
0
// 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")
}
Example #3
0
// 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")
}