Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
1f5f425
refactor: adapt database structure for openbao
noaccOS Mar 23, 2026
26318d9
refactor(fdo): begin refactor to2
AliouneGaye21 Apr 1, 2026
411d44c
refactor: make key algorithm explicit in load voucher (#1886)
frossq Apr 1, 2026
17a61a4
refactor(fdo): replacement voucher and key name (#1887)
AliouneGaye21 Apr 1, 2026
2c4a387
refactor: move create request to fdo_core
noaccOS Apr 1, 2026
d30a44b
test: adjust ownership voucher tests
noaccOS Apr 1, 2026
e7d98e3
test: make tests run
noaccOS Apr 1, 2026
c512f74
increase openbao tests codecov coverage (#1884)
mizzet1 Apr 1, 2026
6795711
test(fdo_core): make test run (#1888)
AliouneGaye21 Apr 1, 2026
41ee83f
test(fdo): restore working tests
noaccOS Apr 1, 2026
ca6c150
refactor(fdo): refactor create voucher on data_access (#1889)
AliouneGaye21 Apr 1, 2026
453d493
build(fdo_core): fix credo
noaccOS Apr 1, 2026
ed58d2d
test(fdo): fix load request tests
noaccOS Apr 1, 2026
ae9d8f9
chore(fdo): remove unused functions
noaccOS Apr 1, 2026
2d35925
feat(pairing): add get keys for algorithm api call (#1890)
mizzet1 Apr 1, 2026
e1c9e8e
chore(secrets): fix ci
noaccOS Apr 1, 2026
109b1c1
chore(fdo): enable TO2.Done tests to work with the new FDO implementa…
frossq Apr 1, 2026
c41e571
refactor: new KEX validation! (#1892)
frossq Apr 2, 2026
ec9dd19
test(data_access): fix tests (#1893)
AliouneGaye21 Apr 2, 2026
ed6afbc
refactor(data_access): fix dialyzer
noaccOS Apr 2, 2026
1de267e
chore: fix function calls
noaccOS Apr 2, 2026
dfe2122
test(fdo): fix load_request tests
noaccOS Apr 2, 2026
dd9b4e9
test(fdo): fix owner_onboarding tests
noaccOS Apr 2, 2026
8194391
chore: make ProveDevice tests working again (#1894)
frossq Apr 2, 2026
627fd63
test(fdo): fix session test (#1895)
AliouneGaye21 Apr 2, 2026
2073836
chore: make ProveDevice/ServiceInfo tests work again (#1898)
frossq Apr 2, 2026
312b224
fix(secrets): fix ecdh signature encoding
noaccOS Apr 2, 2026
638b016
test(fdo): fix fdo onboarding controller (#1899)
AliouneGaye21 Apr 3, 2026
c5bc49c
fix(pairing): re add key algorithm type logic (#1897)
mizzet1 Apr 3, 2026
0e8cd02
chore: fix flakiness in OwnerOnboardingTest (#1900)
frossq Apr 3, 2026
ca6ce51
test(fdo): fix owner_onboarding_test setup_all
noaccOS Apr 3, 2026
de84f85
test(fdo): fix owner onboarding test (#1902)
AliouneGaye21 Apr 3, 2026
092fc7d
test(fdo): merge owner onboarding tests
noaccOS Apr 3, 2026
5367b27
fix(housekeeping): fix ownership_voucher migration table mismatch
mizzet1 Apr 3, 2026
d619fbc
test(secrets): fix flakiness
noaccOS Apr 3, 2026
2c49d2a
fix(pairing): fix ownership_voucher_controller errors (#1904)
mizzet1 Apr 3, 2026
977a6f2
fix(pairing): ensure TO2 messages have correct content type (#1907)
noaccOS Apr 3, 2026
5bd1abb
ci: use stable astarte-device-fdo-rust in e2e (#1908)
noaccOS Apr 7, 2026
f11b412
chore: forward port release-1.3
noaccOS Apr 7, 2026
a80ceb2
chore: forward port master
noaccOS Apr 7, 2026
5b1e9f0
refactor(fdo): re-enable credential reuse logic
AliouneGaye21 Apr 7, 2026
a812efc
refactor: remove assertive ov entry fetch
noaccOS Apr 7, 2026
5defbe2
refactor: move replacement data fetching logic to data_access
noaccOS Apr 7, 2026
d82e276
fix(pairing): fix ownership_voucher_controller errors (#1913)
mizzet1 Apr 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/astarte-apps-build-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ jobs:
--health-interval=2s
--health-timeout=2s
--health-retries=5
rendezvous:
image: astarte/go-fdo-server:ade68cda47-20251128
ports:
- 8041:8041
restart: on-failure
command: '--log-level=debug rendezvous 0.0.0.0:8041 --db-type sqlite --db-dsn "file:/var/lib/fdo/rendezvous.db"'

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/astarte-end-to-end-test-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ jobs:
- name: Checkout fdo e2e repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
repository: astarte-platform/astarte-device-fdo-rust
ref: dev
repository: noaccos/astarte-device-fdo-rust
ref: push-mzlxtwylktkr
- uses: ./.github/actions/install-deps
- name: Install astartectl
run: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,9 +625,15 @@ defmodule Astarte.Housekeeping.Realms.Queries do
defp create_ownership_vouchers_table(keyspace_name) do
query = """
CREATE TABLE #{keyspace_name}.ownership_vouchers (
private_key blob,
voucher_data blob,
guid blob,
voucher_data blob,
output_voucher blob,
replacement_guid blob,
replacement_rendezvous_info blob,
replacement_public_key blob,
key_name varchar,
key_algorithm int,
user_id blob,
PRIMARY KEY (guid)
);
"""
Expand Down Expand Up @@ -673,9 +679,6 @@ defmodule Astarte.Housekeeping.Realms.Queries do
device_service_info map<tuple<text, text>, blob>,
owner_service_info list<blob>,
last_chunk_sent int,
replacement_guid blob,
replacement_rv_info blob,
replacement_pub_key blob,
replacement_hmac blob,
PRIMARY KEY (guid)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE :keyspace.to2_sessions
DROP (replacement_guid, replacement_rv_info, replacement_pub_key)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE :keyspace.ownership_vouchers
DROP private_key
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ALTER TABLE :keyspace.ownership_vouchers
ADD (
replacement_guid blob,
replacement_rendezvous_info blob,
replacement_public_key blob,
output_voucher blob,
key_name varchar,
key_algorithm int,
user_id blob
);
1 change: 1 addition & 0 deletions apps/astarte_pairing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ docker run --rm -d -p 9042:9042 --name scylla scylladb/scylla
docker run --rm -d -p 5672:5672 -p 15672:15672 --name rabbit rabbitmq:3.12.0-management
docker run --rm -d --net=host -p 8080/tcp ispirata/docker-alpine-cfssl-autotest:astarte
docker run --rm -d -p 8200:8200 --name openbao openbao/openbao:latest server -dev -dev-root-token-id=astarte_token
docker run -rm -d -p 8041:8041 --name rendezvous astarte/go-fdo-server:ade68cda47-20251128 --log-level=debug rendezvous 0.0.0.0:8041 --db-type sqlite --db-dsn "file:/var/lib/fdo/rendezvous.db"
```

by default `CASSANDRA_NODES` and `CFSSL_API_URL` environment variables map to localhost, so that
Expand Down
3 changes: 2 additions & 1 deletion apps/astarte_pairing/config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ config :astarte_pairing, :enable_credential_reuse, true

config :astarte_secrets, bao_authentication_mechanism: :token
config :astarte_secrets, bao_token: "astarte_token"
config :astarte_secrets, bao_url: "http://localhost:8200"

config :astarte_fdo, fdo_rendezvous_url: "http://localhost:8041"

config :bcrypt_elixir,
log_rounds: 4
20 changes: 11 additions & 9 deletions apps/astarte_pairing/lib/astarte_pairing/queries.ex
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ defmodule Astarte.Pairing.Queries do
query =
from o in OwnershipVoucher,
prefix: ^keyspace_name,
select: o.private_key
select: o.key_name

consistency = Consistency.domain_model(:read)

Expand All @@ -218,7 +218,7 @@ defmodule Astarte.Pairing.Queries do
realm_name,
guid,
cbor_ownership_voucher,
owner_private_key,
key_name,
ttl
) do
keyspace_name = Realm.keyspace_name(realm_name)
Expand All @@ -227,7 +227,7 @@ defmodule Astarte.Pairing.Queries do

%OwnershipVoucher{
voucher_data: cbor_ownership_voucher,
private_key: owner_private_key,
key_name: key_name,
guid: guid
}
|> Repo.insert(opts)
Expand All @@ -245,13 +245,15 @@ defmodule Astarte.Pairing.Queries do
def replace_ownership_voucher(
realm_name,
guid,
new_voucher,
owner_private_key,
ttl
new_voucher
) do
with {:ok, _} <- delete_ownership_voucher(realm_name, guid) do
create_ownership_voucher(realm_name, guid, new_voucher, owner_private_key, ttl)
end
keyspace = Realm.keyspace_name(realm_name)
consistency = Consistency.device_info(:write)
opts = [prefix: keyspace, consistency: consistency]

%OwnershipVoucher{guid: guid}
|> Ecto.Changeset.change(output_voucher: new_voucher)
|> Repo.update(opts)
end

def store_session(realm_name, guid, session) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,37 @@ defmodule Astarte.PairingWeb.OwnerKeyController do
}
) do
with {:ok, keys} <-
Secrets.Core.get_keys_from_algorithm(realm_name, @supported_key_algorithms) do
Secrets.Core.get_keys(realm_name, @supported_key_algorithms) do
send_resp(conn, 200, Jason.encode!(keys))
end
end

def get_keys_for_algorithm(conn, %{
"realm_name" => realm_name,
"key_algorithm" => key_algorithm
}) do
with {:ok, algorithm} <- Secrets.Core.string_to_key_type(key_algorithm),
{:ok, keys} <- Secrets.Core.get_keys(realm_name, [algorithm]) do
json(conn, %{data: keys})
end
end

def get_key(conn, %{
"realm_name" => realm_name,
"key_algorithm" => key_algorithm,
"key_name" => key_name
}) do
with {:ok, algorithm_atom} <- Secrets.Core.string_to_key_type(key_algorithm) do
case Secrets.Core.find_key(realm_name, algorithm_atom, key_name) do
{:ok, key} ->
json(conn, %{data: %{key_name: key.name, public_key: key.public_pem}})
with {:ok, algorithm_atom} <- Secrets.Core.string_to_key_type(key_algorithm),
{:ok, key} <- Secrets.Core.find_key(realm_name, key_name, algorithm_atom) do
json(conn, %{data: %{key_name: key.name, public_key: key.public_pem}})
else
:error ->
{:error, :unprocessable_key}

:not_found ->
conn
|> put_status(:not_found)
|> json(%{errors: %{detail: "Key not found"}})
end
:not_found ->
conn
|> put_status(:not_found)
|> json(%{errors: %{detail: "Key not found"}})
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -19,54 +19,38 @@
defmodule Astarte.PairingWeb.OwnershipVoucherController do
use Astarte.PairingWeb, :controller

alias Astarte.DataAccess.FDO.OwnershipVoucher.CreateRequest
alias Astarte.FDO.OwnershipVoucher
alias Astarte.FDO.OwnershipVoucher.LoadRequest
alias Astarte.FDO.TO0
alias Astarte.Secrets.Core, as: SecretsCore

action_fallback Astarte.PairingWeb.FallbackController

def create(conn, %{
"data" => data,
"realm_name" => realm_name
}) do
create = CreateRequest.changeset(%CreateRequest{}, data)

with {:ok, create} <- Ecto.Changeset.apply_action(create, :insert),
%CreateRequest{
decoded_ownership_voucher: decoded_ownership_voucher,
cbor_ownership_voucher: cbor_ownership_voucher,
private_key: private_key,
extracted_private_key: extracted_private_key,
device_guid: device_guid
} = create,
:ok <-
OwnershipVoucher.save_voucher(
realm_name,
cbor_ownership_voucher,
device_guid,
private_key
),
:ok <-
TO0.claim_ownership_voucher(
realm_name,
decoded_ownership_voucher,
extracted_private_key
) do
send_resp(conn, 200, "")
end
end

@doc """
Validates an FDO Ownership Voucher load request.
Validates an FDO Ownership Voucher load request and register the OV in the database.

Returns `200 OK` with the owner public key PEM on success.
"""
def register(conn, %{"data" => data, "realm_name" => realm_name}) do
with {:ok, req} <-
LoadRequest.changeset(%LoadRequest{}, Map.put(data, "realm_name", realm_name))
|> Ecto.Changeset.apply_action(:insert) do
|> Ecto.Changeset.apply_action(:insert),
:ok <-
OwnershipVoucher.save_voucher(realm_name, %{
voucher_data: req.cbor_ownership_voucher,
guid: req.device_guid,
key_name: req.key_name,
key_algorithm: req.key_algorithm,
replacement_guid: req.replacement_guid,
replacement_rendezvous_info: req.decoded_replacement_rendezvous_info,
replacement_public_key: req.decoded_replacement_public_key
}),
:ok <-
TO0.claim_ownership_voucher(
realm_name,
req.decoded_ownership_voucher,
req.extracted_owner_key
) do
json(conn, %{
data: %{
public_key: req.extracted_owner_key.public_pem,
Expand All @@ -86,7 +70,7 @@ defmodule Astarte.PairingWeb.OwnershipVoucherController do
with {:ok, pem} <- ensure_ownership_voucher_parameter(data),
{:ok, voucher} <- OwnershipVoucher.decode_binary_voucher(pem),
key_algorithm = OwnershipVoucher.key_algorithm(voucher),
{:ok, keys_map} <- SecretsCore.get_keys_from_algorithm(realm_name, key_algorithm) do
{:ok, keys_map} <- SecretsCore.get_keys(realm_name, key_algorithm) do
json(conn, %{data: keys_map})
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ defmodule Astarte.PairingWeb.Plug.SetupFDO do
case read_body(conn) do
{:ok, body, conn} ->
conn
|> put_resp_header("content-type", "application/cbor")
|> put_resp_header("message-type", to_string(next_message_id))
|> assign(:message_id, message_id)
|> assign(:cbor_body, body)
Expand Down
1 change: 1 addition & 0 deletions apps/astarte_pairing/lib/astarte_pairing_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ defmodule Astarte.PairingWeb.Router do

post "/owner_keys", OwnerKeyController, :create_or_upload_key
get "/owner_keys", OwnerKeyController, :list_keys
get "/owner_keys/:key_algorithm", OwnerKeyController, :get_keys_for_algorithm
get "/owner_keys/:key_algorithm/:key_name", OwnerKeyController, :get_key
post "/owner_keys_for_voucher", OwnershipVoucherController, :owner_keys_for_voucher
post "/ownership_vouchers", OwnershipVoucherController, :register
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,8 @@ defmodule Astarte.PairingWeb.FDOOnboardingControllerTest do
conn: conn,
create_path: path,
message_id: id,
session: session,
realm_name: realm,
owner_key_pem: owner_key_pem,
cbor_ownership_voucher: cbor_ownership_voucher
session: session
} do
insert_voucher(realm, owner_key_pem, cbor_ownership_voucher, session.guid)

request_body = Session.encrypt_and_sign(session, CBOR.encode(%{prove: "device"}))
conn = post(conn, path, request_body)
assert {100, id} == assert_cbor_error(conn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,19 +206,17 @@ defmodule Astarte.PairingWeb.Controllers.OwnerKeyControllerTest do

keys = Jason.decode!(keys)

assert keys == [
%{
"es256" => [
"key_to_create",
"key_to_create1",
"key_to_create2",
"key_to_create3"
]
},
%{"es384" => []},
%{"rs256" => []},
%{"rs384" => []}
]
assert keys == %{
"es256" => [
"key_to_create",
"key_to_create1",
"key_to_create2",
"key_to_create3"
],
"es384" => [],
"rs256" => [],
"rs384" => []
}
end
end

Expand Down
Loading
Loading