Reputation: 1800
I'm trying to implement custom object identifier of ASN1 in Python, these are sample test cases.
asn1_objectidentifier([1,2])
asn1_objectidentifier([1,2,840])
asn1_objectidentifier([1,2,840,5,1000000])
asn1_objectidentifier([1,2,840,5,127,128,129])
What I couldn't manage to do is encoding value3 ... value n in base 128. This is my code so far
def asn1_objectidentifier(oid):
first_octet = 40 * oid[0] + oid[1]
rest = ""
length = 1
for v in range(2, len(oid)):
if oid[v] < 127:
rest += chr(oid[v])
length += 1
else:
rem = oid[v] / 128
first = (rem * 128) ^ 1
second = (oid[v] - first) * 128 ^ 0
rest += int_to_bytestring(first)
rest += int_to_bytestring(second)
length += 2
rest = chr(first_octet) + rest
return chr(0x06) + chr(length) + rest
Upvotes: 0
Views: 1616
Reputation: 123491
Here's a way to do base 128 encoding of non-negative integers:
def base128_encode(n): # int/long to byte string
if n > 0:
arr = []
while n:
n, rem = divmod(n, 128)
arr.append(chr(rem))
return ''.join(reversed(arr))
elif n == 0:
return '\x00'
else:
raise ValueError
print [ord(c) for c in base128_encode(840)] # --> [6, 72]
Upvotes: 2
Reputation: 12514
The excellent article A Layman's Guide to a Subset of ASN.1, BER, and DER describes this in some detail, and – most valuably – gives a number of good test-cases and edge-cases.
By the way: That document doesn't seem to have a canonical home on the web. The above is a link to the CiteseerX reference information; other PDFs exist; and HTML versions.
Upvotes: 2