basic setup of card internal
This commit is contained in:
parent
de3b17c7de
commit
b78526df9b
@ -12,6 +12,7 @@ bug-reports: "https://github.com/username/reponame/issues"
|
|||||||
depends: [
|
depends: [
|
||||||
"ocaml"
|
"ocaml"
|
||||||
"dune" {>= "3.12"}
|
"dune" {>= "3.12"}
|
||||||
|
"hex"
|
||||||
"odoc" {with-doc}
|
"odoc" {with-doc}
|
||||||
]
|
]
|
||||||
build: [
|
build: [
|
||||||
|
140
bin/card.ml
Normal file
140
bin/card.ml
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
open SmartCard
|
||||||
|
|
||||||
|
(** This file contains the default card data *)
|
||||||
|
|
||||||
|
(* EF.CardAccess *)
|
||||||
|
let ef_cardacces =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "\x01\x1C";
|
||||||
|
sid = Bytes.of_string "\x1C";
|
||||||
|
data = Hex.to_bytes (Hex.of_string "3134300d060804007f0007020202020101300f060a04007f000702020302020201013012060a04007f0007020204020202010202010d");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.CardSecurity *)
|
||||||
|
let ef_cardsecurity =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x1D";
|
||||||
|
data = Hex.to_bytes (Hex.of_string "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.DIR *)
|
||||||
|
let ef_dir =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "\x01\x1E";
|
||||||
|
sid = Bytes.of_string "\x1E";
|
||||||
|
data = Hex.to_bytes (Hex.of_string "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.ATR
|
||||||
|
|
||||||
|
The EF.ATR/INFO may be called EF.ATR in contact card
|
||||||
|
standards or specifications, and may be called EF.INFO
|
||||||
|
in contactless card standards or specifications
|
||||||
|
|
||||||
|
The contents of the EF.ATR/INFO can be freely retrieved by using a GET DATA command with
|
||||||
|
P1-P2 = '2F 01' and a command data field of '5C 00' ('00 CB 2F 01 02 5C 00'). The response data field for
|
||||||
|
the GET DATA command is the concatenation of all Data Objects (DO) which are present in EF.ATR/INFO.
|
||||||
|
It contains the BER-TLV content of the EF.ATR/INFO
|
||||||
|
|
||||||
|
*)
|
||||||
|
let ef_atr =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x01";
|
||||||
|
data = Hex.to_bytes (Hex.of_string "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
(* EF.COM *)
|
||||||
|
let ef_com =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x1E";
|
||||||
|
data = Bytes.of_string (Base64.decode_exn "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.DG1 *)
|
||||||
|
let ef_dg1 =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x01";
|
||||||
|
data = Bytes.of_string (Base64.decode_exn "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.DG2 *)
|
||||||
|
let ef_dg2 =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x02";
|
||||||
|
data = Bytes.of_string (Base64.decode_exn "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.DG13 *)
|
||||||
|
let ef_dg13 =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x0D";
|
||||||
|
data = Bytes.of_string (Base64.decode_exn "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.DG14 *)
|
||||||
|
let ef_dg14 =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x0E";
|
||||||
|
data = Bytes.of_string (Base64.decode_exn "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.DG15 *)
|
||||||
|
let ef_dg15 =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x0F";
|
||||||
|
data = Bytes.of_string (Base64.decode_exn "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* EF.SOD *)
|
||||||
|
let ef_sod =
|
||||||
|
Filesystem.ElementaryFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
sid = Bytes.of_string "\x1D";
|
||||||
|
data = Bytes.of_string (Base64.decode_exn "");
|
||||||
|
}
|
||||||
|
|
||||||
|
(* LDS1 eMRTD Application *)
|
||||||
|
let emrtd_application =
|
||||||
|
Filesystem.DelicatedFile {
|
||||||
|
fid = Bytes.of_string "";
|
||||||
|
aid = Some (Bytes.of_string "\xA0\x00\x00\x02\x47\x10\x01");
|
||||||
|
files = [
|
||||||
|
ef_com;
|
||||||
|
ef_dg1;
|
||||||
|
ef_dg2;
|
||||||
|
ef_dg13;
|
||||||
|
ef_dg14;
|
||||||
|
ef_dg15;
|
||||||
|
ef_sod
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
(** The masterfile MF for the card *)
|
||||||
|
let masterfile = Filesystem.DelicatedFile {
|
||||||
|
fid = Bytes.of_string "\x3F\x00";
|
||||||
|
aid = None;
|
||||||
|
files = [
|
||||||
|
ef_cardacces;
|
||||||
|
emrtd_application
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
(** The card can have multiple files, MF included *)
|
||||||
|
let allfiles = [masterfile]
|
||||||
|
|
||||||
|
let custom : CardState.t = {
|
||||||
|
masterfile = Some masterfile;
|
||||||
|
allfiles = allfiles;
|
||||||
|
sm = None;
|
||||||
|
current_file = None;
|
||||||
|
}
|
||||||
|
|
3
bin/dune
3
bin/dune
@ -1,4 +1,5 @@
|
|||||||
|
(env (dev (flags :standard -warn-error -27-32)))
|
||||||
(executable
|
(executable
|
||||||
(public_name apdu)
|
(public_name apdu)
|
||||||
(name main)
|
(name main)
|
||||||
(libraries apdu))
|
(libraries SmartCard hex base64))
|
||||||
|
11
bin/main.ml
11
bin/main.ml
@ -1 +1,10 @@
|
|||||||
let () = print_endline "Hello, World!"
|
let main =
|
||||||
|
let f = SmartCard.Filesystem.find_by_fid (Bytes.of_string "\x01\x1C") Card.custom.allfiles
|
||||||
|
in
|
||||||
|
match f with
|
||||||
|
| Some _ -> print_endline "File found"
|
||||||
|
| None -> print_endline "File not found"
|
||||||
|
|
||||||
|
let hmmge =
|
||||||
|
let command = Bytes.of_string "\x00\x86\x00\x00" in
|
||||||
|
SmartCard.CardState.process command Card.custom
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
(name apdu)
|
(name apdu)
|
||||||
(synopsis "A short synopsis")
|
(synopsis "A short synopsis")
|
||||||
(description "A longer description")
|
(description "A longer description")
|
||||||
(depends ocaml dune)
|
(depends ocaml dune hex)
|
||||||
(tags
|
(tags
|
||||||
(topics "to describe" your project)))
|
(topics "to describe" your project)))
|
||||||
|
|
||||||
|
27
smartcard/CardState.ml
Normal file
27
smartcard/CardState.ml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
(**
|
||||||
|
ICAO 9303 communication is like a state machine,
|
||||||
|
we can make a state machine initialized and for
|
||||||
|
each subsequent commands, modifying the state.
|
||||||
|
So actually we can make an OCAML state machine.
|
||||||
|
*)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
(* a MF may not exist *)
|
||||||
|
masterfile : Filesystem.t option;
|
||||||
|
(* a list of every files in the card *)
|
||||||
|
allfiles : Filesystem.t list;
|
||||||
|
(* encryption scheme *)
|
||||||
|
sm : SecureMessage.t option;
|
||||||
|
(* currently selected file *)
|
||||||
|
current_file : Filesystem.t option;
|
||||||
|
}
|
||||||
|
|
||||||
|
let process command _state =
|
||||||
|
let cm = Command.parse command in
|
||||||
|
match cm.ins with
|
||||||
|
| 0x44 -> print_endline "ACTIVATE FILE"
|
||||||
|
| 0xE2 -> print_endline "APPEND RECORD"
|
||||||
|
| 0x82 -> print_endline "EXTERNAL / MUTUAL AUTHENTICATE"
|
||||||
|
| 0x86 -> print_endline "GENERAL AUTHENTICATE 0x86"
|
||||||
|
| 0x87 -> print_endline "GENERAL AUTHENTICATE 0x87"
|
||||||
|
| _ -> print_endline "NOT IMPLEMENTED"
|
13
smartcard/Command.ml
Normal file
13
smartcard/Command.ml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
type t = {
|
||||||
|
cla : int;
|
||||||
|
ins : int;
|
||||||
|
p1 : int;
|
||||||
|
p2 : int;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parse command = {
|
||||||
|
cla = Bytes.get command 0 |> Char.code;
|
||||||
|
ins = Bytes.get command 1 |> Char.code;
|
||||||
|
p1 = Bytes.get command 2 |> Char.code;
|
||||||
|
p2 = Bytes.get command 3 |> Char.code;
|
||||||
|
}
|
39
smartcard/Filesystem.ml
Normal file
39
smartcard/Filesystem.ml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
type t
|
||||||
|
= DelicatedFile of {
|
||||||
|
fid : Bytes.t;
|
||||||
|
aid : Bytes.t option;
|
||||||
|
files : t list;
|
||||||
|
}
|
||||||
|
| ElementaryFile of {
|
||||||
|
fid : Bytes.t;
|
||||||
|
sid : Bytes.t;
|
||||||
|
data : Bytes.t;
|
||||||
|
}
|
||||||
|
|
||||||
|
let find_by_fid fid files =
|
||||||
|
let rec eachfile = fun file ->
|
||||||
|
match file with
|
||||||
|
| DelicatedFile df -> if Bytes.equal fid df.fid
|
||||||
|
then true
|
||||||
|
else List.exists eachfile df.files
|
||||||
|
| ElementaryFile ef -> Bytes.equal fid ef.fid
|
||||||
|
in
|
||||||
|
List.find_opt eachfile files
|
||||||
|
|
||||||
|
let find_by_aid aid files =
|
||||||
|
let rec eachfile = fun file ->
|
||||||
|
match file with
|
||||||
|
| ElementaryFile _ -> false
|
||||||
|
| DelicatedFile df -> match df.aid with
|
||||||
|
| Some id -> Bytes.equal aid id
|
||||||
|
| None -> List.exists eachfile df.files
|
||||||
|
in
|
||||||
|
List.find_opt eachfile files
|
||||||
|
|
||||||
|
let find_by_sid sid files =
|
||||||
|
let rec eachfile = fun file ->
|
||||||
|
match file with
|
||||||
|
| DelicatedFile df -> List.exists eachfile df.files
|
||||||
|
| ElementaryFile ef -> Bytes.equal sid ef.sid
|
||||||
|
in
|
||||||
|
List.find_opt eachfile files
|
3
smartcard/SecureMessage.ml
Normal file
3
smartcard/SecureMessage.ml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
type t
|
||||||
|
= TripleDES
|
||||||
|
| AES
|
2
smartcard/dune
Normal file
2
smartcard/dune
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
(library
|
||||||
|
(name SmartCard))
|
Loading…
Reference in New Issue
Block a user