1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use apdus::APDU;
use pcsc::*;
pub mod apdus;
pub mod errors;
pub mod tlvs;
pub mod response;
pub fn create_connection() -> Result<Card, errors::TalktoSCError> {
let ctx = match Context::establish(Scope::User) {
Ok(ctx) => ctx,
Err(err) => return Err(errors::TalktoSCError::ContextError(err.to_string())),
};
let mut readers_buf = [0; 2048];
let mut readers = match ctx.list_readers(&mut readers_buf) {
Ok(readers) => readers,
Err(err) => {
return Err(errors::TalktoSCError::ReaderError(err.to_string()));
}
};
let reader = match readers.next() {
Some(reader) => reader,
None => {
return Err(errors::TalktoSCError::MissingReaderError);
}
};
let card = match ctx.connect(reader, ShareMode::Shared, Protocols::ANY) {
Ok(card) => card,
Err(Error::NoSmartcard) => {
return Err(errors::TalktoSCError::MissingSmartCardError);
}
Err(err) => {
return Err(errors::TalktoSCError::SmartCardConnectionError(
err.to_string(),
));
}
};
Ok(card)
}
pub fn disconnect(card: Card) {
let _ = card.disconnect(Disposition::LeaveCard);
}
pub fn sendapdu(card: &Card, apdu: apdus::APDU) -> Vec<u8> {
let l = apdu.iapdus.len();
let mut i = 0;
let mut res: Vec<u8> = Vec::new();
for actual_apdu in &apdu {
let mut resp_buffer = [0; MAX_BUFFER_SIZE];
let resp = card.transmit(&actual_apdu[..], &mut resp_buffer).unwrap();
i += 1;
if i == l {
res = Vec::from(resp);
}
}
return res;
}
pub fn send_and_parse(card: &Card, apdus: APDU) -> Result<response::Response, errors::TalktoSCError> {
response::Response::new(sendapdu(&card, apdus))
}
pub fn entry(_pin: Vec<u8>) {
let card = create_connection().unwrap();
let select_openpgp = apdus::create_apdu_select_openpgp();
let resp = send_and_parse(&card, select_openpgp).unwrap();
println!("Received Final: {:x?}", resp.get_data());
let resp = send_and_parse(&card, apdus::create_apdu_get_aid()).unwrap();
println!("Serial number: {}", tlvs::parse_card_serial(resp.get_data()));
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::Read;
#[test]
fn test_create_newapdu() {
let mut f = File::open("./data/foo2.binary").expect("no file found");
let mut buffer: Vec<u8> = Vec::new();
f.read_to_end(&mut buffer).unwrap();
let comapdu = apdus::APDU::new(0x00, 0x2A, 0x80, 0x86, Some(buffer));
assert_eq!(comapdu.iapdus.len(), 3);
assert_eq!(comapdu.iapdus[0][0], 0x10);
assert_eq!(comapdu.iapdus[1][0], 0x10);
assert_eq!(comapdu.iapdus[2][0], 0x00);
}
}