-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalgorithms.py
252 lines (228 loc) · 8.17 KB
/
algorithms.py
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
# Authors:
# Petr Kubat <[email protected]>
"""
Contains the implementation of extensions for the default PSKC parser
"""
from default import KeyPack
from default import ns
from default import PskcError
class Yubikey(KeyPack):
"""
An extension for the yubikey token
"""
def __init__(self, encrypt):
"""
Initialization method for the object
encrypt -- boolean to see if the package uses encryption
"""
KeyPack.__init__(self, encrypt)
# Yubikey requires AlgorithmParameters
self.algparamreq = True
def parse(self, element):
"""
Extends the default parser
"""
KeyPack.parse(self, element)
try:
if self.devinfo['Manufacturer'] != 'oath.UB':
raise PskcError
if self.devinfo['StartDate'] is None:
raise PskcError
# cryptoid marks ports on the Yubikey token - 1 or 2
if self.cryptoid != '1' and self.cryptoid != '2':
raise PskcError
if (self.algattr['Encoding'] != 'ALPHANUMERIC' or
'Length' not in self.algattr):
raise PskcError
return 0
except (PskcError, KeyError):
print ('Error! Key ' + self.keyinfo['Id'] + ' is not a valid'
' Yubico key.')
return 1
class Hotp(KeyPack):
"""
An extension for the oath HOTP token
"""
def __init__(self, encrypt):
"""
Initialization method for the object
encrypt -- boolean to see if the package uses encryption
"""
KeyPack.__init__(self, encrypt)
# HOTP requires AlgorithmParameters
self.algparamreq = True
def parse(self, element):
"""
Extends the default parser
"""
KeyPack.parse(self, element)
try:
# Encoding and Lenght both need to be set
if 'Encoding' not in self.algattr or 'Length' not in self.algattr:
raise PskcError
# Encoding needs to be DECIMAL
if self.algattr['Encoding'] != 'DECIMAL':
raise PskcError
# Counter needs to be present
if 'Counter' not in self.keydata:
raise PskcError
return 0
except PskcError:
print ('Error! Key ' + self.keyinfo['Id'] + ' is not a valid '
'HOTP key.')
return 1
class Totp(KeyPack):
"""
An extension for the oath TOTP token
"""
def __init__(self, encrypt):
"""
Initialization method for the object
encrypt -- boolean to see if the package uses encryption
"""
KeyPack.__init__(self, encrypt)
# TOTP requires AlgorithmParameters
self.algparamreq = True
# TOTP requires Key policy (Usage)
self.keypolicyreq = True
def parse(self, element):
"""
Extends the default parser
"""
KeyPack.parse(self, element)
try:
# Encoding and Lenght both need to be set
if 'Encoding' not in self.algattr or 'Length' not in self.algattr:
raise PskcError
# Time and TimeInterval elements need to be present in the key data
if 'Time' not in self.keydata or 'TimeInterval' not in self.keydata:
raise PskcError
# Encoding needs to be DECIMAL
if self.algattr['Encoding'] != 'DECIMAL':
raise PskcError
return 0
except PskcError:
print ('Error! Key ' + self.keyinfo['Id'] + ' is not a valid '
'TOTP key.')
return 1
# ! Following extensions might be outdated !
class SecurIdAes(KeyPack):
"""
An extension for RSA's SecurID token using AES
"""
def __init__(self, encrypt):
"""
Initialization method for the object
encrypt -- boolean to see if the package uses encryption
"""
KeyPack.__init__(self, encrypt)
# SecurID requires AlgorithmParameters
self.algparamreq = True
# SecurID requires Key policy
self.keypolicyreq = True
def parse(self, element):
"""
Extends the default parser
"""
KeyPack.parse(self, element)
try:
# Start date and expiry date both need to be set
if ('StartDate' not in self.policyinfo or
'ExpiryDate' not in self.policyinfo):
raise PskcError
# Encoding needs to be DECIMAL
if self.algattr['Encoding'] != 'DECIMAL':
raise PskcError
# Length needs to be at least 6
if int(self.algattr['Length']) < 6:
raise PskcError
return 0
except PskcError:
print ('Error! Key ' + self.keyinfo['Id'] + ' is not a valid '
'TOTP key.')
return 1
class SecurIdCntr(KeyPack):
"""
An extension for RSA's SecurID token using AES with a counter
"""
def __init__(self, encrypt):
"""
Initialization method for the object
encrypt -- boolean to see if the package uses encryption
"""
KeyPack.__init__(self, encrypt)
# SecurID requires AlgorithmParameters
self.algparamreq = True
# SecurID requires Key policy
self.keypolicyreq = True
def parse(self, element):
"""
Extends the default parser
"""
KeyPack.parse(self, element)
try:
# Start date and expiry date both need to be set
if ('StartDate' not in self.policyinfo or
'ExpiryDate' not in self.policyinfo):
raise PskcError
# Encoding needs to be DECIMAL
if self.algattr['Encoding'] != 'DECIMAL':
raise PskcError
# Length needs to be at least 6
if int(self.algattr['Length']) < 6:
raise PskcError
# Counter needs to be present
if 'Counter' not in self.keydata:
raise PskcError
return 0
except PskcError:
print ('Error! Key ' + self.keyinfo['Id'] + ' is not a valid '
'TOTP key.')
return 1
class SecurIdAlgor(KeyPack):
"""
An extension for RSA's SecurID token using ALGOR
"""
def __init__(self, encrypt):
"""
Initialization method for the object
encrypt -- boolean to see if the package uses encryption
"""
# SecurID requires AlgorithmParameters
self.algparamreq = True
# SecurID requires Key policy
self.keypolicyreq = True
KeyPack.__init__(self, encrypt)
def parse(self, element):
"""
Extends the default parser
"""
KeyPack.parse(self, element)
try:
# Start date and expiry date both need to be set
if ('StartDate' not in self.policyinfo or
'ExpiryDate' not in self.policyinfo):
raise PskcError
# Encoding needs to be DECIMAL
if self.algattr['Encoding'] != 'DECIMAL':
raise PskcError
# Length needs to be at least 6
if int(self.algattr['Length']) < 6:
raise PskcError
return 0
except PskcError:
print ('Error! Key ' + self.keyinfo['Id'] + ' is not a valid '
'TOTP key.')
return 1
# A dict for calling extensions in the main program
alglist = {'http://www.yubico.com/#yubikey-aes' : Yubikey,
'urn:ietf:params:xml:ns:keyprov:pskc:hotp' : Hotp,
'urn:ietf:params:xml:ns:keyprov:pskc#totp' : Totp,
# ! Following algorithm URIs are probably outdated !
'http://www.rsasecurity.com/rsalabs/otps/schemas/2005/09/'
'otps-wst#SecurID-AES' : SecurIdAes,
'http://www.rsa.com/names/2008/04/algorithms/SecurID/'
'SecurID-AES128-Counter' : SecurIdCntr,
'http://www.rsasecurity.com/rsalabs/otps/schemas/2005/09/'
'otps-wst#SecurID-ALGOR' : SecurIdAlgor
}