1+ from __future__ import division
2+
13import binascii
24import base64
5+ from .six import int2byte , b , PY3 , integer_types , text_type
36
47class UnexpectedDER (Exception ):
58 pass
69
710def encode_constructed (tag , value ):
8- return chr (0xa0 + tag ) + encode_length (len (value )) + value
11+ return int2byte (0xa0 + tag ) + encode_length (len (value )) + value
912def encode_integer (r ):
1013 assert r >= 0 # can't support negative numbers yet
11- h = "%x" % r
12- if len (h )% 2 :
13- h = "0" + h
14+ h = ( "%x" % r ). encode ()
15+ if len (h ) % 2 :
16+ h = b ( "0" ) + h
1417 s = binascii .unhexlify (h )
15- if ord (s [0 ]) <= 0x7f :
16- return "\x02 " + chr (len (s )) + s
18+ num = s [0 ] if isinstance (s [0 ], integer_types ) else ord (s [0 ])
19+ if num <= 0x7f :
20+ return b ("\x02 " ) + int2byte (len (s )) + s
1721 else :
1822 # DER integers are two's complement, so if the first byte is
1923 # 0x80-0xff then we need an extra 0x00 byte to prevent it from
2024 # looking negative.
21- return "\x02 " + chr (len (s )+ 1 ) + "\x00 " + s
25+ return b ( "\x02 " ) + int2byte (len (s )+ 1 ) + b ( "\x00 " ) + s
2226
2327def encode_bitstring (s ):
24- return "\x03 " + encode_length (len (s )) + s
28+ return b ( "\x03 " ) + encode_length (len (s )) + s
2529def encode_octet_string (s ):
26- return "\x04 " + encode_length (len (s )) + s
30+ return b ( "\x04 " ) + encode_length (len (s )) + s
2731def encode_oid (first , second , * pieces ):
2832 assert first <= 2
2933 assert second <= 39
30- encoded_pieces = [chr (40 * first + second )] + [encode_number (p )
31- for p in pieces ]
32- body = "" .join (encoded_pieces )
33- return " \x06 " + encode_length (len (body )) + body
34+ encoded_pieces = [int2byte (40 * first + second )] + [encode_number (p )
35+ for p in pieces ]
36+ body = b ( '' ) .join (encoded_pieces )
37+ return b ( ' \x06 ' ) + encode_length (len (body )) + body
3438def encode_sequence (* encoded_pieces ):
3539 total_len = sum ([len (p ) for p in encoded_pieces ])
36- return " \x30 " + encode_length (total_len ) + "" .join (encoded_pieces )
40+ return b ( ' \x30 ' ) + encode_length (total_len ) + b ( '' ) .join (encoded_pieces )
3741def encode_number (n ):
3842 b128_digits = []
3943 while n :
@@ -42,10 +46,10 @@ def encode_number(n):
4246 if not b128_digits :
4347 b128_digits .append (0 )
4448 b128_digits [- 1 ] &= 0x7f
45- return "" .join ([chr (d ) for d in b128_digits ])
49+ return b ( '' ) .join ([int2byte (d ) for d in b128_digits ])
4650
4751def remove_constructed (string ):
48- s0 = ord (string [0 ])
52+ s0 = string [ 0 ] if isinstance ( string [ 0 ], integer_types ) else ord (string [0 ])
4953 if (s0 & 0xe0 ) != 0xa0 :
5054 raise UnexpectedDER ("wanted constructed tag (0xa0-0xbf), got 0x%02x"
5155 % s0 )
@@ -56,26 +60,26 @@ def remove_constructed(string):
5660 return tag , body , rest
5761
5862def remove_sequence (string ):
59- if not string .startswith ("\x30 " ):
60- raise UnexpectedDER ( "wanted sequence (0x30), got 0x%02x" %
61- ord ( string [ 0 ]) )
63+ if not string .startswith (b ( "\x30 " ) ):
64+ n = string [ 0 ] if isinstance ( string [ 0 ], integer_types ) else ord ( string [ 0 ])
65+ raise UnexpectedDER ( "wanted sequence (0x30), got 0x%02x" % n )
6266 length , lengthlength = read_length (string [1 :])
6367 endseq = 1 + lengthlength + length
6468 return string [1 + lengthlength :endseq ], string [endseq :]
6569
6670def remove_octet_string (string ):
67- if not string .startswith ("\x04 " ):
68- raise UnexpectedDER ( "wanted octetstring (0x04), got 0x%02x" %
69- ord ( string [ 0 ]) )
71+ if not string .startswith (b ( "\x04 " ) ):
72+ n = string [ 0 ] if isinstance ( string [ 0 ], integer_types ) else ord ( string [ 0 ])
73+ raise UnexpectedDER ( "wanted octetstring (0x04), got 0x%02x" % n )
7074 length , llen = read_length (string [1 :])
7175 body = string [1 + llen :1 + llen + length ]
7276 rest = string [1 + llen + length :]
7377 return body , rest
7478
7579def remove_object (string ):
76- if not string .startswith ("\x06 " ):
77- raise UnexpectedDER ( "wanted object (0x06), got 0x%02x" %
78- ord ( string [ 0 ]) )
80+ if not string .startswith (b ( "\x06 " ) ):
81+ n = string [ 0 ] if isinstance ( string [ 0 ], integer_types ) else ord ( string [ 0 ])
82+ raise UnexpectedDER ( "wanted object (0x06), got 0x%02x" % n )
7983 length , lengthlength = read_length (string [1 :])
8084 body = string [1 + lengthlength :1 + lengthlength + length ]
8185 rest = string [1 + lengthlength + length :]
@@ -92,13 +96,14 @@ def remove_object(string):
9296 return tuple (numbers ), rest
9397
9498def remove_integer (string ):
95- if not string .startswith ("\x02 " ):
96- raise UnexpectedDER ( "wanted integer (0x02), got 0x%02x" %
97- ord ( string [ 0 ]) )
99+ if not string .startswith (b ( "\x02 " ) ):
100+ n = string [ 0 ] if isinstance ( string [ 0 ], integer_types ) else ord ( string [ 0 ])
101+ raise UnexpectedDER ( "wanted integer (0x02), got 0x%02x" % n )
98102 length , llen = read_length (string [1 :])
99103 numberbytes = string [1 + llen :1 + llen + length ]
100104 rest = string [1 + llen + length :]
101- assert ord (numberbytes [0 ]) < 0x80 # can't support negative numbers yet
105+ nbytes = numberbytes [0 ] if isinstance (numberbytes [0 ], integer_types ) else ord (numberbytes [0 ])
106+ assert nbytes < 0x80 # can't support negative numbers yet
102107 return int (binascii .hexlify (numberbytes ), 16 ), rest
103108
104109def read_number (string ):
@@ -109,7 +114,7 @@ def read_number(string):
109114 if llen > len (string ):
110115 raise UnexpectedDER ("ran out of length bytes" )
111116 number = number << 7
112- d = ord (string [llen ])
117+ d = string [ llen ] if isinstance ( string [ llen ], integer_types ) else ord (string [llen ])
113118 number += (d & 0x7f )
114119 llen += 1
115120 if not d & 0x80 :
@@ -119,29 +124,30 @@ def read_number(string):
119124def encode_length (l ):
120125 assert l >= 0
121126 if l < 0x80 :
122- return chr (l )
123- s = "%x" % l
127+ return int2byte (l )
128+ s = ( "%x" % l ). encode ()
124129 if len (s )% 2 :
125- s = "0" + s
130+ s = b ( "0" ) + s
126131 s = binascii .unhexlify (s )
127132 llen = len (s )
128- return chr (0x80 | llen ) + s
133+ return int2byte (0x80 | llen ) + s
129134
130135def read_length (string ):
131- if not (ord (string [0 ]) & 0x80 ):
136+ num = string [0 ] if isinstance (string [0 ], integer_types ) else ord (string [0 ])
137+ if not (num & 0x80 ):
132138 # short form
133- return (ord ( string [ 0 ]) & 0x7f ), 1
139+ return (num & 0x7f ), 1
134140 # else long-form: b0&0x7f is number of additional base256 length bytes,
135141 # big-endian
136- llen = ord ( string [ 0 ]) & 0x7f
142+ llen = num & 0x7f
137143 if llen > len (string )- 1 :
138144 raise UnexpectedDER ("ran out of length bytes" )
139145 return int (binascii .hexlify (string [1 :1 + llen ]), 16 ), 1 + llen
140146
141147def remove_bitstring (string ):
142- if not string . startswith ( " \x03 " ):
143- raise UnexpectedDER ( "wanted bitstring (0x03), got 0x%02x" %
144- ord ( string [ 0 ]) )
148+ num = string [ 0 ] if isinstance ( string [ 0 ], integer_types ) else ord ( string [ 0 ])
149+ if not string . startswith ( b ( " \x03 " )):
150+ raise UnexpectedDER ( "wanted bitstring (0x03), got 0x%02x" % num )
145151 length , llen = read_length (string [1 :])
146152 body = string [1 + llen :1 + llen + length ]
147153 rest = string [1 + llen + length :]
@@ -177,14 +183,17 @@ def remove_bitstring(string):
177183# iso(1) identified-organization(3) certicom(132) curve(0) 34 }
178184
179185def unpem (pem ):
180- d = "" .join ([l .strip () for l in pem .split ("\n " )
181- if l and not l .startswith ("-----" )])
186+ if isinstance (pem , text_type ):
187+ pem = pem .encode ()
188+
189+ d = b ("" ).join ([l .strip () for l in pem .split (b ("\n " ))
190+ if l and not l .startswith (b ("-----" ))])
182191 return base64 .b64decode (d )
183192def topem (der , name ):
184193 b64 = base64 .b64encode (der )
185- lines = ["-----BEGIN %s-----\n " % name ]
186- lines .extend ([b64 [start :start + 64 ]+ "\n "
194+ lines = [( "-----BEGIN %s-----\n " % name ). encode () ]
195+ lines .extend ([b64 [start :start + 64 ]+ b ( "\n " )
187196 for start in range (0 , len (b64 ), 64 )])
188- lines .append ("-----END %s-----\n " % name )
189- return "" .join (lines )
197+ lines .append (( "-----END %s-----\n " % name ). encode () )
198+ return b ( "" ) .join (lines )
190199
0 commit comments