Skip to content
Open

Arm #12

Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion PROJECT_OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ pip install -r requirements.txt
python app.py
```

**Backend runs on:** http://localhost:5000
**Backend runs on:** http://3.17.71.163:5000

### **Step 2: Open POS Simulator**

Expand Down
2 changes: 1 addition & 1 deletion WEBSOCKET_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ cd backend/api
python app.py
```

The server will start on `http://localhost:5000` with WebSocket support.
The server will start on `http://3.17.71.163:5000` with WebSocket support.

### 3. Start the Mobile App

Expand Down
10 changes: 9 additions & 1 deletion backend/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from dotenv import load_dotenv
from twilio.rest import Client
import secrets
from arm import run_arc_verify

# Load environment variables
load_dotenv()
Expand Down Expand Up @@ -123,7 +124,14 @@ def generate_demo_keys():
# Mock attestation verification (for hackathon)
def verify_attestation(attestation_token):
"""Verify device attestation token (mock for hackathon)"""
return attestation_token and attestation_token.startswith('mock_attestation_')

result = run_arc_verify(attestation_token)
if result.overall_affirming:
return True
else:
return False

# return attestation_token and attestation_token.startswith('mock_attestation_')

def verify_signature(data, signature, private_key):
"""Verify digital signature (simplified for demo)"""
Expand Down
129 changes: 129 additions & 0 deletions backend/api/arm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env python3
import os
import re
import sys
import shutil
import subprocess
from dataclasses import dataclass
from typing import Dict, Tuple, Optional

@dataclass
class VerifyResult:
raw_output: str
instance_identity_by_submod: Dict[str, str] # e.g., {"CCA_REALM": "affirming", "CCA_SSD_PLATFORM": "affirming"}
overall_affirming: bool
returncode: int

def parse_instance_identity_status(text: str) -> Tuple[Dict[str, str], bool]:
"""
Parse ARC verifier output and extract the 'Instance Identity' status for each submodule.

Returns (per_submod_status, overall_affirming) where:
- per_submod_status maps submod name -> status string (lowercased, e.g. 'affirming', 'warning', 'none', etc.)
- overall_affirming is True iff all present submodules have status 'affirming'
"""
per_submod: Dict[str, str] = {}
current_submod: Optional[str] = None
submod_header = re.compile(r"\s*submod\(([^)]+)\):\s*$")
inst_identity_line = re.compile(r"\s*Instance Identity\s*\[([^\]]+)\]\s*:\s*(.*)$", re.IGNORECASE)

for line in text.splitlines():
m = submod_header.match(line)
if m:
current_submod = m.group(1).strip()
continue
if current_submod:
mi = inst_identity_line.match(line)
if mi:
status = mi.group(1).strip().lower()
per_submod[current_submod] = status
# don't reset current_submod; there may be other lines in same section we ignore

overall = bool(per_submod) and all(v == "affirming" for v in per_submod.values())
return per_submod, overall


def run_arc_verify(
arc_dir: str = "ear/arc",
pkey_path: Optional[str] = None,
jwt_path: Optional[str] = None,
timeout: int = 120,
) -> VerifyResult:
import pathlib, os, shutil, subprocess

# Resolve paths safely
arc_dir_abs = pathlib.Path(arc_dir).expanduser().resolve()
home = pathlib.Path(os.path.expanduser("~")).resolve()

pkey = pathlib.Path(pkey_path or home / "pkey.json")
jwt = pathlib.Path(jwt_path or home / "attestation_result.jwt")

if not arc_dir_abs.is_dir():
raise FileNotFoundError(f"ARC directory not found: {arc_dir_abs}")
arc_bin = arc_dir_abs / "arc"
if not arc_bin.exists():
raise FileNotFoundError(f"'arc' binary not found at {arc_bin}")
if not os.access(arc_bin, os.X_OK):
raise PermissionError(f"'arc' exists but is not executable: {arc_bin} (try: chmod +x '{arc_bin}')")
if not pkey.exists():
raise FileNotFoundError(f"pkey not found: {pkey}")
if not jwt.exists():
raise FileNotFoundError(f"JWT not found: {jwt}")

# Run './arc' inside its directory
cmd = ["./arc", "verify", "--pkey", str(pkey), str(jwt)]
proc = subprocess.run(
cmd,
cwd=str(arc_dir_abs),
text=True,
capture_output=True,
timeout=timeout,
)
output = (proc.stdout or "") + ("\n" + proc.stderr if proc.stderr else "")
per_submod, overall = parse_instance_identity_status(output)

return VerifyResult(
raw_output=output,
instance_identity_by_submod=per_submod,
overall_affirming=overall,
returncode=proc.returncode,
)


def main():
# Allow optional CLI overrides:
# python verify_instance_identity.py [arc_dir] [pkey_path] [jwt_path]
arc_dir = sys.argv[1] if len(sys.argv) > 1 else "ear/arc"
pkey_path = sys.argv[2] if len(sys.argv) > 2 else None
jwt_path = sys.argv[3] if len(sys.argv) > 3 else None

try:
result = run_arc_verify(arc_dir=arc_dir, pkey_path=pkey_path, jwt_path=jwt_path)
except Exception as e:
print(f"[ERROR] {e}", file=sys.stderr)
sys.exit(2)

# Display a concise summary, plus per-submodule details for clarity.
print("=== ARC Verify Output (truncated to decision) ===")
if result.instance_identity_by_submod:
for submod, status in result.instance_identity_by_submod.items():
print(f"submod({submod}): Instance Identity -> {status}")
else:
print("No 'Instance Identity' lines found in output.")

print("\nOverall Instance Identity Affirming:", "YES" if result.overall_affirming else "NO")

# Exit status semantics:
# 0 -> success AND overall affirming
# 1 -> ran but not overall affirming
# 2 -> local error (missing files, timeout, etc.)
if result.overall_affirming and result.returncode == 0:
sys.exit(0)
else:
# Still show raw output to aid debugging if it's not affirming
print("\n--- Full Command Output ---\n")
print(result.raw_output)
sys.exit(1)

if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion backend/api/test_api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import requests
import json

BASE_URL = "http://localhost:5000/api"
BASE_URL = "http://3.17.71.163:5000/api"

def test_health():
"""Test health check endpoint."""
Expand Down
11 changes: 11 additions & 0 deletions backend/api/testing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
return "Hello from ec2"

if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)

Binary file not shown.
6 changes: 3 additions & 3 deletions frontend/transaction-simulator.html
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ <h1>ProxyPay Transaction Simulator</h1>

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.js"></script>
<script>
const API_URL = "http://localhost:5000/api/transaction/validate";
const WS_URL = "http://localhost:5000";
const API_URL = "http://3.17.71.163:5000/api/transaction/validate";
const WS_URL = "http://3.17.71.163:5000";

// Initialize WebSocket connection
const socket = io(WS_URL);
Expand Down Expand Up @@ -530,7 +530,7 @@ <h1>ProxyPay Transaction Simulator</h1>
} catch (error) {
console.error("Transaction error:", error);
showError(
"Failed to request location proof. Make sure the backend is running on http://localhost:5000"
"Failed to request location proof. Make sure the backend is running on http://3.17.71.163:5000"
);
}
});
Expand Down
2 changes: 1 addition & 1 deletion mobile-app/src/examples/CryptoExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class CryptoExample {

// Register with backend
const response = await fetch(
"http://localhost:5000/api/register-device",
"http://3.17.71.163:5000/api/register-device",
{
method: "POST",
headers: {
Expand Down
2 changes: 1 addition & 1 deletion mobile-app/src/services/LocationProofService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class LocationProofService {
signature: string
): Promise<ProofSubmissionResult> {
try {
const response = await fetch("http://localhost:5000/api/prove-location", {
const response = await fetch("http://3.17.71.163:5000/api/prove-location", {
method: "POST",
headers: {
"Content-Type": "application/json",
Expand Down