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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
//! SE/Linux EHR IDL file
//! Author: SE/Linux team <se-linux@inso.tuwien.ac.at>
module Ehr {
sequence<byte> ByteSeq;
//! Base class for exceptions
exception EhrException {
string what; //! Detailed error message.
};
//! The request could not be validated.
exception InvalidRequestException extends EhrException { };
//! An account specified in the request is invalid.
exception InvalidAccountException extends InvalidRequestException { };
//! The signature of the request could not be verified.
exception SignatureException extends EhrException { };
//! The requestor is not allowed to perform the request.
exception PermissionDeniedException extends EhrException { };
//! Identifies an account in the SEPM/Linux EHR system
struct AccountIdentifier {
string user; //! User part of account
string provider; //! Provider part of account
};
enum DocumentType {
DOCANY,
DOCPRESCRIPTION,
DOCCONSUMEDPRESCRIPTION
};
//! The signature of a request.
//!
//! To calculate the signature of a request object, the request object is
//! serialized (converted to a byte stream) using the streaming interface.
//! See chapter 36.2 (Streaming Interface) of the ICE manual for details.
//!
//! Then, the SHA1 hash of the byte stream is calculated and encrypted using
//! the private key of the account that issued the request.
//! See EVP_SignInit(3SSL) for details.
//!
//! This signature logic is implemented in Security::sign
struct Signature {
ByteSeq data;
};
struct Timestamp {
//! The time since the Epoch (00:00:00 UTC, January 1, 1970),
//! measured in milliseconds.
long msecs;
};
struct Date {
byte day;
byte month;
short year;
};
enum AccessType {
ALLOW, //! Allow access
DENY //! Deny access
};
//! An envelope encrypted serialized document.
//!
//! The document is a class or structure serialized (converted to a byte stream)
//! using the ICE streaming interface.
//! See chapter 36.2 (Streaming Interface) of the ICE manual for details.
//!
//! The byte stream is encrypted using envolope encryption: it is encrypted with
//! a symetric cipher (AES) using a random key. This key is then encrypted with
//! the public key (RSA) of the owner.
//!
//! See EVP_SealInit(3) for details on envelope encryption.
//!
//! This encryption logic is also implemented in Security::encryptPublic.
struct EncryptedDocument {
//! AES key encrypted with the RSA public key of the owner.
ByteSeq encryptedKey;
//! The initial vector for AES (aes_256_cbc).
ByteSeq initialVector;
//! Document encrypted with AES (aes_256_cbc).
ByteSeq encryptedData;
};
//! Base class for documents in the EHR.
class Document {
//! The document type.
DocumentType type;
};
//! The prescription document created by the physician.
class Prescription extends Document {
string originatorName;
string originatorProfession;
string originatorAddress;
Date creationDate;
string consumerName;
Date consumerDateOfBirth;
string drugDescription;
string form;
int dosage;
string measuringUnit;
Date validFrom;
Date expires;
};
//! The prescription consumption created by the pharmacist.
//! It contains a copy of the original prescription.
class ConsumedPrescription extends Prescription {
string dispenserName;
string dispenserProfession;
string dispenserAddress;
Date dispensingDate;
};
//! Base class for a request to a provider node.
class Request {
//! The account that issued the request.
AccountIdentifier requestor;
//! Timestamp when the request was issued.
//! A reasonable provider node validates the timestamp, for example:
//! (timestamp_last_request_from_requestor < when) && (when < now() + 1_min)
//! The first condition guarantees that requests can't be reused.
Timestamp when;
};
//! Base class for requests where two parties are involved, for example
//! a patient and a pharmacist.
class ThirdPartyRequest extends Request {
//! The account that owns the EHR (patient).
AccountIdentifier owner;
};
//! Request to creaete a prescription.
//! Issued by a physician and aproved by the patient.
class CreatePrescriptionRequest extends ThirdPartyRequest {
//! A serialized Prescription encrypted with the public key of the patient.
EncryptedDocument prescription;
};
//! Issued by a pharmacist and aproved by the patient.
class ConsumePrescriptionRequest extends ThirdPartyRequest {
//! Id of the prescription to consume
long prescriptionId;
//! The serialized ConsumePrescription encrypted with the public key of the patient.
EncryptedDocument consumedPrescription;
};
//! Request to list all documents in an EHR.
//! Issued by anyone.
//! Aproved by the patient.
class ListDocumentsRequest extends ThirdPartyRequest {
};
//! Request to find documents in an EHR.
//! Issued by anyone.
//! Aproved by the patient.
class FindDocumentsRequest extends ThirdPartyRequest {
bool hasFrom; //! If true, the from field is valid.
Timestamp from; //! Search documents older than from.
bool hasTill; //! If true, the till field is valid.
Timestamp till; //! Search documents younger than till.
//! Search only documents of the given type.
//! Set to DOCANY if the document type does not matter.
DocumentType type;
//! Search only document with the giben ID.
//! Set to 0 if the ID does not matter.
long documentId;
};
//! Request to create a pemission on a document.
//! Issued by patient only.
class CreatePermissionRequest extends Request {
//! The id of the document.
long documentId;
//! The account the permission belongs to.
AccountIdentifier account;
//! The access type (ALLOW, DENY).
AccessType access;
};
//! Request to set the default permission on a docment.
//! The default permission determines, whether access is granted to an
//! account, for which there is no explicit permission available.
//! Issued by patient only.
class SetDefaultAccessRequest extends Request {
//! The id of the document.
long documentId;
//! The access type (ALLOW, DENY).
AccessType access;
};
//! Request to request the list of permissions on a document.
//! Issued by patient only.
class ListPermissionsRequest extends Request {
//! The id of the document.
long documentId;
};
//! Request to remove a permission form a document.
//! Issued by patient only.
class RemovePermissionRequest extends Request {
//! The id of the document.
long documentId;
//! The id of the permission to remove.
long permissionId;
};
//! Combines an encrypted document with an id.
struct DocumentListItem {
long id;
Timestamp created;
EncryptedDocument document;
};
sequence<DocumentListItem> DocumentList;
//! Combines a permission with an id.
struct AccessControlListItem {
long id;
AccountIdentifier account;
AccessType access;
};
sequence<AccessControlListItem> AccessControlList;
//! The permissions for a document.
struct Permissions {
//! Default permission, if there is no explicit permission in the acl.
AccessType defaultAccess;
//! Per account permissions.
AccessControlList acl;
};
//! The interface of a provider node for client software.
//!
//! Every method has the following arguments:
//!
//! - A request object.
//! - The signature of the request object by the requesting party.
//! - If the requetor is different form the owner of the EHR (for example
//! a pharmacist), the signature of the owner of the EHR.
interface Provider {
void createPrescription(
CreatePrescriptionRequest request,
Signature requestorSignature,
Signature ownerSignature
) throws EhrException;
void consumePrescription(
ConsumePrescriptionRequest request,
Signature requestorSignature,
Signature ownerSignature
) throws EhrException;
DocumentList listDocuments(
ListDocumentsRequest request,
Signature requestorSignature,
Signature ownerSignature
) throws EhrException;
DocumentList findDocuments(
FindDocumentsRequest request,
Signature requestorSignature,
Signature ownerSignature
) throws EhrException;
void setDefaultAccess(
SetDefaultAccessRequest request,
Signature requestorSignature
) throws EhrException;
void createPermission(
CreatePermissionRequest request,
Signature requestorSignature
) throws EhrException;
Permissions listPermissions(
ListPermissionsRequest request,
Signature requestorSignature
) throws EhrException;
void removePermission(
RemovePermissionRequest request,
Signature requestorSignature
) throws EhrException;
};
};
|