Skip to content

Commit

Permalink
Merge branch 'master' of github.com:synrc/ca
Browse files Browse the repository at this point in the history
  • Loading branch information
5HT committed Nov 20, 2024
2 parents c55c80a + 85ab617 commit 8946061
Show file tree
Hide file tree
Showing 42 changed files with 3,521 additions and 4,100 deletions.
49 changes: 49 additions & 0 deletions EUDI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
EU Digital Identity
===================

SYNRC CA server supports EUDI.

### Architecture

EUDI is decentralized PKIX with ABAC level control over attributes that is using JSON as encoding and HTTP as transport.

* eIDAS Node (CA) -- State Certificate Authority (SAML/HTTP, PKIX, JSON/HTTP)
* EUDI Verification Service Provider (VSP), Verifier -- Verifiable Presentations (VP, mDOC)
* EUID Wallet, Holder -- iOS/Android Application (PKIX, mDOC, OpenID4VC)
* EUDI Trusted Service Provider (TSP), Issuer -- OpenID for Verifiable Credentials (OpenID4VC, mDOC, SAML)
* Personal Identification Data (PID) Provider -- Diia State Enterprise (MSO mDOC)
* Qualified and Non-Qualified Electronic Attestation of Attributes (QEAA) Schema Providers (MSO mDOC)
* Qualifiied Electronic Signature Provider (QSP) -- Qualified Certificates (QC)

### Holder, Issuer, Verifier

In an OpenID4VC ecosystem, the Verifier and the Issuer are connected indirectly
through the credential lifecycle, with interactions primarily mediated by the Holder.
This architecture ensures trust without requiring a direct, continuous relationship
between the Verifier and the Issuer, adhering to privacy and decentralizition principles.
The Verifier does not contact the Issuer directly during routine operations unless a
status check is necessary. The Holder acts as an intermediary, maintaining privacy
and control over shared data.

EUDI Wallet acts as Holder, QEAA, EAA, PIP (TSPs) act as EUDI Providers or Issuers.
EUDI Verifier perform status verification of credentials and acts as presentations Verifier.

### PKIX vs EUDI

EUDI model has a similarity with PKIX.
The same way person use a signed attribute set (a X.509 certificate from CSR attributes)
for authentication and authorization in PKI, the OpenID4VC provider (PIP) envelops
set of attributes (digital presentation of claims) and
issue and Electronic Documents in mDOC format for EUDI Wallet.

Unlike PKIX, EUDI relies on a centralized model with a single root CA,
EUDI employs a distributed model where all parties are cryptographically bound.
EUDI enforces more rigorous control over attributes (claims), akin to the ABAC model.

CRLs and OCSP can create privacy concerns since they involve
querying a CA, potentially exposing the user's activity.
OpenID4VC mitigates this by enabling the Holder to mediate
the process, and some implementations avoid real-time statu
checks entirely by including cryptographic proofs within the
credential itself.

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

## Features

* PKI Entities: `CA`, `RA`, `SERVER`, `CLIENT`, `HUMAN`, `PROGRAM`
* PKI entities: `CA`, `RA`, `SERVER`, `CLIENT`, `HUMAN`, `PROGRAM`
* Key purposes: `TLS`, `ECDSA`, `AES`, `SSH`, `SCVP`, `IPSEC`, `CMC`, `SIP`, `CAP`, `EAP`, `BGP`, `OCSP`
* EUID documents: `TAXID`, `PID`, `IBAN`, `HIID`, `LOYAL`
* Curve profiles: `secp256k1`, `secp384r1`, `secp521r1`
* DH Schemes: `RSA`, `GF(p)`, `GF(2^m)`
* RFC: CMS, PKCS-10, CMP, ESP, OCSP, TSP
Expand Down
4 changes: 4 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import Config

config :ca,
enabled: [:issuer, :wallet, :verifier, :est, :cmp, :cmc, :ocsp, :tsp],
issuer: 8107,
wallet: 8108,
verifier: 8109,
est: 8047,
cmp: 8829,
cmc: 5318,
Expand Down
51 changes: 51 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,59 @@ <h3>DEVELOPMENT</h3>
* <a href="https://tonpa.guru/stream/2023/2023-08-13 SWIFT X.509.htm">2023-08-13 SWIFT X.509</a><br>
* <a href="https://tonpa.guru/stream/2023/2023-09-01 ASN1.EX X.680.htm">2023-09-01 ASN1.EX X.680</a><br>
* <a href="https://tonpa.guru/stream/2024/2024-10-29 EST.htm">2024-10-29 EST</a><br>
* <a href="https://tonpa.guru/stream/2024/2024-11-17 EUDI.htm">2024-11-17 EUDI</a><br>

</p>
</section>
<section>
<h3>ARCHITECTURE</h3>

<p>EUDI is decetralized PKIX with ABAC level control over attributes that is using JSON as encoding and HTTP as transport.</p>

<p>
<ul>
<li>● eIDAS Node &mdash; State Certificate Authority</li>
<li>● EUDI Verifier &mdash; Verifiable Presentations</li>
<li>● EUID Wallet (Holder) &mdash; iOS/Android Application </li>
<li>● EUDI Provider (Issuer) &mdash; OpenID for Verifiable Credentials</li>
<li>● Personal Identification Data (PID) Provider &mdash; Diia State Enterprise</li>
<li>● Qualified and Non-Qualified Electronic Attestation of Attributes (QEAA)</li>
<li>● Qualifiied Electronic Signature Provider (QP) &mdash; Qualified Certificates (QC)</li>
</ul>
</p>

<h4>HOLDER, ISSUER, VERIFIER</h4>

<p>In an OpenID4VC ecosystem, the Verifier and the Issuer are connected indirectly
through the credential lifecycle, with interactions primarily mediated by the Holder.
This architecture ensures trust without requiring a direct, continuous relationship
between the Verifier and the Issuer, adhering to privacy and decentralization principles.
The Verifier does not directly contact the Issuer during typical operations unless a status check is required.
The Holder acts as the intermediary, ensuring their privacy and control over the data being shared.</p>

<p>EUDI Wallet acts as Holder, QEAA, EAA, PIP (TSPs) act as EUDI Providers or Issuers. EUDI Verifier perform
status verification of credentials and acts as presentations Verifier.</P>

<h4>PKIX vs OpenID4VC</h4>

<p>EUDI model has a similarity with PKIX.
The same way person use a signed attribute set (a X.509 certificate from CSR attributes)
for authentication and authorization in PKI, the OpenID4VC provider (PIP) envelops
set of attributes (digital presentation of claims) and
issue and Electronic Documents in mDOC format for EUDI Wallet.</p>

<p>However, unlike PKIX with its centralized model,
EUDI provide distributed model without single root CA,
where all parties bounded cryptographycally. Also, EUDI has more subtle
and rigorous control over attributes (claims) like in ABAC model.</p>

<p>CRLs and OCSP can create privacy concerns since they involve
querying a CA, potentially exposing the user's activity.
OpenID4VC mitigates this by enabling the Holder to mediate
the process, and some implementations avoid real-time statu
checks entirely by including cryptographic proofs within the
credential itself.</p>

<br>
<br><center>&dot;</center>
</section>
Expand Down
6 changes: 4 additions & 2 deletions lib/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ defmodule CA do
{ CA.CMC, port: port(:cmc) },
{ CA.OCSP, port: port(:ocsp) },
{ CA.TSP, port: port(:tsp) },
{ CA.EST, port: port(:est), plug: CA.EST, scheme: :http,
thousand_island_options: [num_acceptors: 1] }
{ CA.EUDI.Issuer, port: port(:issuer), plug: CA.EUDI.Issuer, scheme: :http, thousand_island_options: [num_acceptors: 1] },
{ CA.EUDI.Verifier, port: port(:verifier), plug: CA.EUDI.Verifier, scheme: :http, thousand_island_options: [num_acceptors: 1] },
{ CA.EUDI.Wallet, port: port(:wallet), plug: CA.EUDI.Wallet, scheme: :http, thousand_island_options: [num_acceptors: 1] },
{ CA.EST, port: port(:est), plug: CA.EST, scheme: :http, thousand_island_options: [num_acceptors: 1] }
], strategy: :one_for_one, name: CA.Supervisor)
end

Expand Down
4 changes: 4 additions & 0 deletions lib/eudi/eudi.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
defmodule CA.EUDI do
@moduledoc "CA/EUDI/OID4VC HTTPS/HTTP library."

end
42 changes: 42 additions & 0 deletions lib/eudi/issuer.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
defmodule CA.EUDI.Issuer do
@moduledoc "EUDI/OID4VC Issuer server."
@profiles [ "secp256k1", "secp384r1", "secp521r1" ]

Check warning on line 3 in lib/eudi/issuer.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @profiles was set but never used
@templates [ "ocsp", "ipsec", "bgp", "eap", "cap", "sip", "cmc", "scvp", "ssh", "tls" ]

Check warning on line 4 in lib/eudi/issuer.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @templates was set but never used
@classes [ "ca", "ra", "server", "client", "human", "program" ]

Check warning on line 5 in lib/eudi/issuer.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @classes was set but never used

use Plug.Router
plug :match
plug :dispatch
plug Plug.Parsers, parsers: [:json], json_decoder: Jason

def start_link(opt) do
Bandit.start_link(opt)
end

def child_spec(opt) do
%{
id: EUDI.Issuer,
start: {CA.EUDI.Issuer, :start_link, [opt]},
type: :supervisor,
restart: :permanent
}
end

get "/jwks" do CA.EST.Get.get(conn, "EUDI", [], [], "JWKS") end
get "/.well-known/openid-configuration" do CA.EST.Get.get(conn, "EUDI", [], [], "CONFIG") end
get "/.well-known/openid-credential-issuer" do CA.EST.Get.get(conn, "EUDI", [], [], "ISSUE") end
get "/.well-known/oauth-authorization-server" do CA.EST.Get.get(conn, "EUDI", [], [], "OAUTH") end
get "/.well-known/jwt-vc-issuer" do CA.EST.Get.get(conn, "EUDI", [], [], "JWT") end
get "/openid4vc/credentialOffer" do CA.EST.Get.get(conn, "EUDI", [], [], "OFFER") end
post "/openid4vc/jwt/issue" do CA.EST.Get.get(conn, "EUDI", [], [], "JWT") end
post "/openid4vc/sdjwt/issue" do CA.EST.Get.get(conn, "EUDI", [], [], "SDJWT") end
post "/openid4vc/mdoc/issue" do CA.EST.Get.get(conn, "EUDI", [], [], "MDOC") end

match _ do send_resp(conn, 404, "Please refer to https://authority.erp.uno for more information.\n") end
def encode(x) do
case Jason.encode(x) do
{:ok, bin} -> bin
{:error, _} -> ""
end |> Jason.Formatter.pretty_print
end
end
38 changes: 38 additions & 0 deletions lib/eudi/verifier.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule CA.EUDI.Verifier do
@moduledoc "EUDI/OID4VC Verifier."
@profiles [ "secp256k1", "secp384r1", "secp521r1" ]

Check warning on line 3 in lib/eudi/verifier.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @profiles was set but never used
@templates [ "ocsp", "ipsec", "bgp", "eap", "cap", "sip", "cmc", "scvp", "ssh", "tls" ]

Check warning on line 4 in lib/eudi/verifier.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @templates was set but never used
@classes [ "ca", "ra", "server", "client", "human", "program" ]

Check warning on line 5 in lib/eudi/verifier.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @classes was set but never used

use Plug.Router
plug :match
plug :dispatch
plug Plug.Parsers, parsers: [:json], json_decoder: Jason

def start_link(opt) do
Bandit.start_link(opt)
end

def child_spec(opt) do
%{
id: EUDI.Verifier,
start: {CA.EUDI.Verifier, :start_link, [opt]},
type: :supervisor,
restart: :permanent
}
end

get "/openid4vc/session/:id" do CA.EST.Get.get(conn, "EUDI", [], id, "SESSION") end
get "/openid4vc/policy-list" do CA.EST.Get.get(conn, "EUDI", [], [], "POLICIES") end
get "/openid4vc/pd/:id" do CA.EST.Get.get(conn, "EUDI", [], id, "PD") end
get "/openid4vc/verify/:state" do CA.EST.Get.get(conn, "EUDI", [], state, "VERIFY") end
get "/openid4vc/request/:id" do CA.EST.Get.get(conn, "EUDI", [], id, "REQ") end

match _ do send_resp(conn, 404, "Please refer to https://authority.erp.uno for more information.\n") end
def encode(x) do
case Jason.encode(x) do
{:ok, bin} -> bin
{:error, _} -> ""
end |> Jason.Formatter.pretty_print
end
end
40 changes: 40 additions & 0 deletions lib/eudi/wallet.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule CA.EUDI.Wallet do
@moduledoc "EUDI/OID4VC Wallet web application server."
@profiles [ "secp256k1", "secp384r1", "secp521r1" ]
@templates [ "ocsp", "ipsec", "bgp", "eap", "cap", "sip", "cmc", "scvp", "ssh", "tls" ]

Check warning on line 4 in lib/eudi/wallet.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @templates was set but never used
@classes [ "ca", "ra", "server", "client", "human", "program" ]

Check warning on line 5 in lib/eudi/wallet.ex

View workflow job for this annotation

GitHub Actions / build

module attribute @classes was set but never used

use Plug.Router
plug :match
plug :dispatch
plug Plug.Parsers, parsers: [:json], json_decoder: Jason

def start_link(opt) do
Bandit.start_link(opt)
end

def child_spec(opt) do
%{
id: EUDI.Wallet,
start: {CA.EUDI.Wallet, :start_link, [opt]},
type: :supervisor,
restart: :permanent
}
end

get "/wallets" do CA.EST.Get.get(conn, "EUDI", [], [], "WALLETS") end
get "/wallets/:id/dids" do CA.EST.Get.get(conn, "EUDI", [], [], "DIDS") end
get "/wallets/:id/keys" do CA.EST.Get.get(conn, "EUDI", [], [], "KEYS") end
get "/wallets/:id/credentials" do CA.EST.Get.get(conn, "EUDI", [], [], "CREDS") end
get "/wallets/:id/issuers" do CA.EST.Get.get(conn, "EUDI", [], [], "ISSUERS") end
get "/wallets/:id/exchange" do CA.EST.Get.get(conn, "EUDI", [], [], "EXCHANGES") end
get "/wallets/parseMDoc" do CA.EST.Get.get(conn, "EUDI", [], [], "MDOC") end

match _ do send_resp(conn, 404, "Please refer to https://authority.erp.uno for more information.\n") end
def encode(x) do
case Jason.encode(x) do
{:ok, bin} -> bin
{:error, _} -> ""
end |> Jason.Formatter.pretty_print
end
end
6 changes: 6 additions & 0 deletions lib/services/http/get.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ defmodule CA.EST.Get do
@profiles ["secp256k1","secp384r1","secp521r1"]
import Plug.Conn

def get(conn, _, _, _, _) do
end

def get(conn, "CA", profile, _, "CA") when profile in @profiles do
body = :base64.encode(CA.CSR.read_ca_public(profile))
conn |> put_resp_content_type("application/pkix-cert")
Expand Down Expand Up @@ -41,4 +44,7 @@ defmodule CA.EST.Get do
send_resp(conn, 200, CA.EST.encode([%{"template" => template, "curve" => curve, "operation" => operation}]))
end

def get(conn, _, _, _, _) do
end

end
13 changes: 10 additions & 3 deletions priv/kep/DSTU.asn1 → priv/cms/DSTU.asn1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Certificate ::= SEQUENCE {
Certificates ::= SEQUENCE OF Certificate

TBSCertificate ::= SEQUENCE {
version [0] Version,
version [0] Version DEFAULT v3,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
Expand All @@ -23,7 +23,7 @@ TBSCertificate ::= SEQUENCE {
extensions [3] EXPLICIT Extensions }

UniqueIdentifier ::= BIT STRING
Version ::= INTEGER {v3 (2)}
Version ::= INTEGER { v1(0), v2(1), v3(2) }
CertificateSerialNumber ::= INTEGER
Name ::= CHOICE { rdnSequence RDNSequence }
RDNSequence::= SEQUENCE OF RelativeDistinguishedName
Expand All @@ -40,7 +40,7 @@ Extension ::= SEQUENCE {
extnvalue OCTET STRING }

AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= ANY -- DEFINED BY AttributeType
AttributeValue ::= ANY --DEFINED BY AttributeType
DirectoryString ::= CHOICE {
printableString PrintableString,
utf8String UTF8String,
Expand All @@ -60,6 +60,13 @@ SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }

AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY }
-- DEFINED BY algorithm OPTIONAL

OctetString ::= OCTET STRING

DSTU4145Params::= SEQUENCE {
definition CHOICE { ecbinary ECBinary, namedCurve OBJECT IDENTIFIER },
dke OCTET STRING OPTIONAL }
Expand Down
49 changes: 49 additions & 0 deletions priv/csr/EUDI.asn1
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
EUDI DEFINITIONS ::=
BEGIN

id-eleg OBJECT IDENTIFIER ::= {iso(1) member-body(2) se(752) e-legitimationsnamnden(201)}

-- Sweden Connect arcs
id-mod OBJECT IDENTIFIER ::= { id-eleg 0 } -- ASN.1 modules
id-test OBJECT IDENTIFIER ::= { id-eleg 1 } -- OIDs for test
id-pol OBJECT IDENTIFIER ::= { id-eleg 2 } -- Policy
id-attr OBJECT IDENTIFIER ::= { id-eleg 3 } -- Attributes
id-qcs OBJECT IDENTIFIER ::= { id-eleg 4 } -- QC Statement
id-ce OBJECT IDENTIFIER ::= { id-eleg 5 } -- Cert Extensions

-- Sweden Connect Modules
id-mod-auth-context-88 OBJECT IDENTIFIER ::= { id-mod 1 } -- Used in RFC 7773
id-mod-auth-context-08 OBJECT IDENTIFIER ::= { id-mod 2 } -- Used in RFC 7773

-- Sweden Connect OIDs for test

-- Sweden Connect Policies
id-pol-svt-ts-policy OBJECT IDENTIFIER ::= { id-pol 1 } -- SVT RFC 3161 timestamp policy

-- Sweden Connect Attributes
id-attr-org-affiliation OBJECT IDENTIFIER ::= { id-attr 1 } -- Organizational affiliation
id-attr-transaction-id OBJECT IDENTIFIER ::= { id-attr 2 } -- Transaction identifier
id-attr-auth-context-params OBJECT IDENTIFIER ::= { id-attr 3 } -- Authentication context parameters
id-attr-prid OBJECT IDENTIFIER ::= { id-attr 4 } -- Provisional ID
id-attr-prid-persistence OBJECT IDENTIFIER ::= { id-attr 5 } -- Provisional ID persistence indicator
id-attr-pnr-binding OBJECT IDENTIFIER ::= { id-attr 6 } -- Personal Identity Number binding URI
id-attr-eidas-pid OBJECT IDENTIFIER ::= { id-attr 7 } -- eIDAS Person Identifier
id-attr-birth-name OBJECT IDENTIFIER ::= { id-attr 8 } -- Birth name
id-attr-eidas-np-address OBJECT IDENTIFIER ::= { id-attr 9 } -- eIDAS Natural Person Address
id-attr-user-certificate OBJECT IDENTIFIER ::= { id-attr 10 } -- User certificate
id-attr-user-signature OBJECT IDENTIFIER ::= { id-attr 11 } -- User signature
id-attr-sad OBJECT IDENTIFIER ::= { id-attr 12 } -- Signature activation data
id-attr-auth-srv-signature OBJECT IDENTIFIER ::= { id-attr 13 } -- Authentication server signature
id-attr-sign-message-digest OBJECT IDENTIFIER ::= { id-attr 14 } -- Sign message digest
id-attr-previous-pid-number OBJECT IDENTIFIER ::= { id-attr 15 } -- Previous personal identity number
id-attr-mapped-pid-number OBJECT IDENTIFIER ::= { id-attr 16 } -- Mapped personal identity number

-- Sweden Connect QC Statement extension
id-qcs-sid OBJECT IDENTIFIER ::= { id-qcs 1 } -- Semantics Identifiers
id-qcs-statement OBJECT IDENTIFIER ::= { id-qcs 2 } -- QC statements

-- Sweden Connect Certificate Extensions
id-ce-authContext OBJECT IDENTIFIER ::= { id-ce 1 } -- Auth context extension used in RFC 7773
id-ce-svt OBJECT IDENTIFIER ::= { id-ce 2 } -- Signature Validation Token extension

END
Loading

0 comments on commit 8946061

Please sign in to comment.