Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
scapy
Manage
Activity
Members
Plan
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CodeLinaro
public-release-test-restored
platform
external
scapy
Commits
36bbb8ff
Commit
36bbb8ff
authored
8 years ago
by
mtu
Browse files
Options
Downloads
Patches
Plain Diff
ASN.1 enhancements
parent
870770bc
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
scapy/asn1/asn1.py
+68
-25
68 additions, 25 deletions
scapy/asn1/asn1.py
scapy/asn1/ber.py
+5
-3
5 additions, 3 deletions
scapy/asn1/ber.py
scapy/asn1fields.py
+18
-27
18 additions, 27 deletions
scapy/asn1fields.py
with
91 additions
and
55 deletions
scapy/asn1/asn1.py
+
68
−
25
View file @
36bbb8ff
...
...
@@ -262,19 +262,42 @@ class ASN1_BIT_STRING(ASN1_Object):
"""
tag
=
ASN1_Class_UNIVERSAL
.
BIT_STRING
def
__init__
(
self
,
val
,
readable
=
False
):
if
readable
:
self
.
val_readable
=
val
val
=
""
.
join
(
binrepr
(
ord
(
x
)).
zfill
(
8
)
for
x
in
val
)
self
.
unused_bits
=
0
if
not
readable
:
self
.
val
=
val
else
:
if
len
(
val
)
%
8
==
0
:
self
.
unused_bits
=
0
self
.
val_readable
=
val
def
__setattr__
(
self
,
name
,
value
):
if
name
==
"
val_readable
"
:
if
isinstance
(
value
,
str
):
val
=
""
.
join
(
binrepr
(
ord
(
x
)).
zfill
(
8
)
for
x
in
value
)
else
:
self
.
unused_bits
=
8
-
len
(
val
)
%
8
padded_val
=
val
+
"
0
"
*
self
.
unused_bits
bytes_arr
=
zip
(
*
[
iter
(
padded_val
)]
*
8
)
self
.
val_readable
=
""
.
join
(
chr
(
int
(
""
.
join
(
x
),
2
))
for
x
in
bytes_arr
)
ASN1_Object
.
__init__
(
self
,
val
)
val
=
"
<invalid val_readable>
"
super
(
ASN1_Object
,
self
).
__setattr__
(
"
val
"
,
val
)
super
(
ASN1_Object
,
self
).
__setattr__
(
name
,
value
)
super
(
ASN1_Object
,
self
).
__setattr__
(
"
unused_bits
"
,
0
)
elif
name
==
"
val
"
:
if
isinstance
(
value
,
str
):
if
len
([
c
for
c
in
value
if
c
not
in
[
"
0
"
,
"
1
"
]])
>
0
:
print
"
Invalid operation:
'
val
'
is not a valid bit string.
"
return
else
:
if
len
(
value
)
%
8
==
0
:
unused_bits
=
0
else
:
unused_bits
=
8
-
(
len
(
value
)
%
8
)
padded_value
=
value
+
(
"
0
"
*
unused_bits
)
bytes_arr
=
zip
(
*
[
iter
(
padded_value
)]
*
8
)
val_readable
=
""
.
join
(
chr
(
int
(
""
.
join
(
x
),
2
))
for
x
in
bytes_arr
)
else
:
val_readable
=
"
<invalid val>
"
unused_bits
=
0
super
(
ASN1_Object
,
self
).
__setattr__
(
"
val_readable
"
,
val_readable
)
super
(
ASN1_Object
,
self
).
__setattr__
(
name
,
value
)
super
(
ASN1_Object
,
self
).
__setattr__
(
"
unused_bits
"
,
unused_bits
)
elif
name
==
"
unused_bits
"
:
print
"
Invalid operation: unused_bits rewriting is not supported.
"
else
:
super
(
ASN1_Object
,
self
).
__setattr__
(
name
,
value
)
def
__repr__
(
self
):
if
len
(
self
.
val
)
<=
16
:
return
"
<%s[%r] (%d unused bit%s)>
"
%
(
self
.
__dict__
.
get
(
"
name
"
,
self
.
__class__
.
__name__
),
self
.
val
,
self
.
unused_bits
,
"
s
"
if
self
.
unused_bits
>
1
else
""
)
...
...
@@ -327,26 +350,46 @@ class ASN1_IA5_STRING(ASN1_STRING):
class
ASN1_UTC_TIME
(
ASN1_STRING
):
tag
=
ASN1_Class_UNIVERSAL
.
UTC_TIME
def
__init__
(
self
,
val
):
pretty_time
=
""
if
len
(
val
)
==
13
and
val
[
-
1
]
==
"
Z
"
:
dt
=
datetime
.
strptime
(
val
[:
-
1
],
"
%y%m%d%H%M%S
"
)
pretty_time
=
dt
.
strftime
(
"
%b %d %H:%M:%S %Y GMT
"
)
self
.
pretty_time
=
pretty_time
ASN1_STRING
.
__init__
(
self
,
val
)
super
(
ASN1_UTC_TIME
,
self
).
__init__
(
val
)
def
__setattr__
(
self
,
name
,
value
):
if
name
==
"
val
"
:
pretty_time
=
None
if
(
isinstance
(
value
,
str
)
and
len
(
value
)
==
13
and
value
[
-
1
]
==
"
Z
"
):
dt
=
datetime
.
strptime
(
value
[:
-
1
],
"
%y%m%d%H%M%S
"
)
pretty_time
=
dt
.
strftime
(
"
%b %d %H:%M:%S %Y GMT
"
)
else
:
pretty_time
=
"
%s [invalid utc_time]
"
%
value
super
(
ASN1_UTC_TIME
,
self
).
__setattr__
(
"
pretty_time
"
,
pretty_time
)
super
(
ASN1_UTC_TIME
,
self
).
__setattr__
(
name
,
value
)
elif
name
==
"
pretty_time
"
:
print
"
Invalid operation: pretty_time rewriting is not supported.
"
else
:
super
(
ASN1_UTC_TIME
,
self
).
__setattr__
(
name
,
value
)
def
__repr__
(
self
):
return
self
.
pretty_time
+
"
"
+
ASN1_STRING
.
__repr__
(
self
)
return
"
%s %s
"
%
(
self
.
pretty_time
,
ASN1_STRING
.
__repr__
(
self
)
)
class
ASN1_GENERALIZED_TIME
(
ASN1_STRING
):
tag
=
ASN1_Class_UNIVERSAL
.
GENERALIZED_TIME
def
__init__
(
self
,
val
):
pretty_time
=
""
if
len
(
val
)
==
15
and
val
[
-
1
]
==
"
Z
"
:
dt
=
datetime
.
strptime
(
val
[:
-
1
],
"
%Y%m%d%H%M%S
"
)
pretty_time
=
dt
.
strftime
(
"
%b %d %H:%M:%S %Y GMT
"
)
self
.
pretty_time
=
pretty_time
ASN1_STRING
.
__init__
(
self
,
val
)
super
(
ASN1_GENERALIZED_TIME
,
self
).
__init__
(
val
)
def
__setattr__
(
self
,
name
,
value
):
if
name
==
"
val
"
:
pretty_time
=
None
if
(
isinstance
(
value
,
str
)
and
len
(
value
)
==
15
and
value
[
-
1
]
==
"
Z
"
):
dt
=
datetime
.
strptime
(
value
[:
-
1
],
"
%Y%m%d%H%M%S
"
)
pretty_time
=
dt
.
strftime
(
"
%b %d %H:%M:%S %Y GMT
"
)
else
:
pretty_time
=
"
%s [invalid generalized_time]
"
%
value
super
(
ASN1_GENERALIZED_TIME
,
self
).
__setattr__
(
"
pretty_time
"
,
pretty_time
)
super
(
ASN1_GENERALIZED_TIME
,
self
).
__setattr__
(
name
,
value
)
elif
name
==
"
pretty_time
"
:
print
"
Invalid operation: pretty_time rewriting is not supported.
"
else
:
super
(
ASN1_GENERALIZED_TIME
,
self
).
__setattr__
(
name
,
value
)
def
__repr__
(
self
):
return
self
.
pretty_time
+
"
"
+
ASN1_STRING
.
__repr__
(
self
)
return
"
%s %s
"
%
(
self
.
pretty_time
,
ASN1_STRING
.
__repr__
(
self
)
)
class
ASN1_ISO646_STRING
(
ASN1_STRING
):
tag
=
ASN1_Class_UNIVERSAL
.
ISO646_STRING
...
...
This diff is collapsed.
Click to expand it.
scapy/asn1/ber.py
+
5
−
3
View file @
36bbb8ff
...
...
@@ -105,13 +105,15 @@ def BER_id_dec(s):
# This returns the tag ALONG WITH THE PADDED CLASS+CONSTRUCTIVE INFO.
# Let's recall that bits 8-7 from the first byte of the tag encode
# the class information, while bit 6 means primitive or constructive.
#
# For instance, with low-tag-number '\x81', class would be 0b10
# ('context-specific') and tag 0x01, but we return 0x81 as a whole.
# For '\xff\x
0
2', class would be 0b11 ('private'), constructed, then
# padding, then tag 0x
0
2, but we return (0xff>>5)*128^1 + 0x
0
2*128^0.
# For '\xff\x
2
2', class would be 0b11 ('private'), constructed, then
# padding, then tag 0x
2
2, but we return (0xff>>5)*128^1 + 0x
2
2*128^0.
# Why the 5-bit-shifting? Because it provides an unequivocal encoding
# on base 128 (note that 0xff would equal 1*128^1 + 127*128^0...),
# as we know that bits 5 to 1 are fixed to 1 anyway.
#
# As long as there is no class differentiation, we have to keep this info
# encoded in scapy's tag in order to reuse it for packet building.
# Note that tags thus may have to be hard-coded with their extended
...
...
@@ -394,7 +396,7 @@ class BERcodec_ISO646_STRING(BERcodec_STRING):
class
BERcodec_UNIVERSAL_STRING
(
BERcodec_STRING
):
tag
=
ASN1_Class_UNIVERSAL
.
UNIVERSAL_STRING
class
BERcodec_BMP_STRING
(
BERcodec_STRING
):
class
BERcodec_BMP_STRING
(
BERcodec_STRING
):
tag
=
ASN1_Class_UNIVERSAL
.
BMP_STRING
class
BERcodec_SEQUENCE
(
BERcodec_Object
):
...
...
This diff is collapsed.
Click to expand it.
scapy/asn1fields.py
+
18
−
27
View file @
36bbb8ff
...
...
@@ -179,26 +179,16 @@ class ASN1F_enum_INTEGER(ASN1F_INTEGER):
for
k
in
keys
:
i2s
[
k
]
=
enum
[
k
]
s2i
[
enum
[
k
]]
=
k
def
any2i_one
(
self
,
pkt
,
x
):
if
type
(
x
)
is
str
:
x
=
self
.
s2i
[
x
]
return
x
def
any2i
(
self
,
pkt
,
x
):
if
type
(
x
)
is
list
:
return
map
(
lambda
z
,
pkt
=
pkt
:
self
.
any2i_one
(
pkt
,
z
),
x
)
else
:
return
self
.
any2i_one
(
pkt
,
x
)
def
i2repr_one
(
self
,
pkt
,
x
):
if
x
is
not
None
:
r
=
self
.
i2s
.
get
(
x
)
def
i2m
(
self
,
pkt
,
s
):
if
isinstance
(
s
,
str
):
s
=
self
.
s2i
.
get
(
s
)
return
super
(
ASN1F_INTEGER
,
self
).
i2m
(
pkt
,
s
)
def
i2repr
(
self
,
pkt
,
x
):
if
x
is
not
None
and
isinstance
(
x
,
ASN1_INTEGER
):
r
=
self
.
i2s
.
get
(
x
.
val
)
if
r
:
return
r
+
"
"
+
repr
(
x
)
return
"'
%s
'
%s
"
%
(
r
,
repr
(
x
)
)
return
repr
(
x
)
def
i2repr
(
self
,
pkt
,
x
):
if
type
(
x
)
is
list
:
return
map
(
lambda
z
,
pkt
=
pkt
:
self
.
i2repr_one
(
pkt
,
z
),
x
)
else
:
return
self
.
i2repr_one
(
pkt
,
x
)
class
ASN1F_BIT_STRING
(
ASN1F_field
):
ASN1_tag
=
ASN1_Class_UNIVERSAL
.
BIT_STRING
...
...
@@ -479,22 +469,23 @@ class ASN1F_CHOICE(ASN1F_field):
else
:
choice
=
self
.
choices
[
tag
]
if
hasattr
(
choice
,
"
ASN1_root
"
):
# we don't want to import ASN1_Packet in this module...
return
self
.
extract_packet
(
choice
,
s
)
elif
type
(
choice
)
is
type
:
#XXX find a way not to instantiate the ASN1F_field
return
choice
(
self
.
name
,
""
).
m2i
(
pkt
,
s
)
else
:
if
type
(
choice
)
is
type
:
return
choice
(
self
.
name
,
""
).
m2i
(
pkt
,
s
)
else
:
# choice must be an ASN1F_PACKET instance here
return
choice
.
m2i
(
pkt
,
s
)
#XXX check properly if this is an ASN1F_PACKET
return
choice
.
m2i
(
pkt
,
s
)
def
i2m
(
self
,
pkt
,
x
):
if
x
is
None
:
s
=
""
else
:
s
=
str
(
x
)
if
hash
(
type
(
x
))
in
self
.
pktchoices
:
imp
,
exp
=
self
.
pktchoices
[
hash
(
type
(
x
))]
s
=
BER_tagging_enc
(
s
,
implicit_tag
=
imp
,
explicit_tag
=
exp
)
if
hash
(
type
(
x
))
in
self
.
pktchoices
:
imp
,
exp
=
self
.
pktchoices
[
hash
(
type
(
x
))]
s
=
BER_tagging_enc
(
s
,
implicit_tag
=
imp
,
explicit_tag
=
exp
)
return
BER_tagging_enc
(
s
,
explicit_tag
=
self
.
explicit_tag
)
def
randval
(
self
):
return
RandChoice
(
*
(
packet
.
fuzz
(
x
())
for
x
in
self
.
choices
.
itervalues
()))
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment