def get_size(self, d): """Get total octet count of a body specified by new length header octs. :Parameters: - `d`: string of "new" length octets, note that this string cannot be made up of arbitrary bytes, and must conform to the rules of new length values (rfc2440 4.2.2) :Returns: XXXXXXX TODO Example: >>> newlength_octets = [0xff, 0x92, 0xdf, 0x7c, 0xbb] >>> newlength_data_string = ''.join(map(chr, length_octet_list)) >>> newlength = NewLength() >>> newlength.get_size(newlength_data_string) 2464119995 """ idx = size = 0 # the length_list is to keep track of data (d) actually used - # it's possible that a string of partials could terminate with # leftover octets length_list = [] if 0 < len(d): for L in [(x, ord(x)) for x in d]: if L[1] < 192: size = size + L[1] length_list.append(L[0]) break elif 192 <= L[1] <= 223: slice = d[idx:idx + 2] s = STN.doubleoct2int(slice) if 192 <= s <= 8383: # ?? dunno about this restriction size = size + s length_list.append(slice) else: raise PGPFormatError( "New double octet lengths are confined to the range 192 <= x <= 8383. Received: data->(%s) length->(%s)" % (d, size)) break elif 255 == L[1]: slice = d[idx:idx + 5] size = size + STN.pentoct2int(slice) length_list.append(slice) break elif 224 <= L[1] <= 254: # partials slice = d[idx:idx + 1] size = size + STN.partial2int(slice) length_list.append(slice) idx = idx + 1 else: raise PGPFormatError( "Length must have at least one octet. Received len(d) == 0.") return size, length_list
def get_size(self, d): """Get total octet count of a body specified by new length header octs. :Parameters: - `d`: string of "new" length octets, note that this string cannot be made up of arbitrary bytes, and must conform to the rules of new length values (rfc2440 4.2.2) :Returns: XXXXXXX TODO Example: >>> newlength_octets = [0xff, 0x92, 0xdf, 0x7c, 0xbb] >>> newlength_data_string = ''.join(map(chr, length_octet_list)) >>> newlength = NewLength() >>> newlength.get_size(newlength_data_string) 2464119995 """ idx = size = 0 # the length_list is to keep track of data (d) actually used - # it's possible that a string of partials could terminate with # leftover octets length_list = [] if 0 < len(d): for L in [(x, ord(x)) for x in d]: if L[1] < 192: size = size + L[1] length_list.append(L[0]) break elif 192 <= L[1] <= 223: slice = d[idx:idx+2] s = STN.doubleoct2int(slice) if 192 <= s <= 8383: # ?? dunno about this restriction size = size + s length_list.append(slice) else: raise PGPFormatError("New double octet lengths are confined to the range 192 <= x <= 8383. Received: data->(%s) length->(%s)" % (d, size)) break elif 255 == L[1]: slice = d[idx:idx+5] size = size + STN.pentoct2int(slice) length_list.append(slice) break elif 224 <= L[1] <= 254: # partials slice = d[idx:idx+1] size = size + STN.partial2int(slice) length_list.append(slice) idx = idx + 1 else: raise PGPFormatError("Length must have at least one octet. Received len(d) == 0.") return size, length_list
def testD2Sanity(self): """strnum: double octet inversion (int2doubleoct/doubleoct2int)""" for o in self.good_double_octs: self.assertEqual(o[0], doubleoct2int(int2doubleoct(o[0])))
def testC6OctTranslation(self): """strnum: doubleoct2int output""" for v in self.good_double_octs: self.assertEqual(v[0], doubleoct2int(v[1]))
def fill(self, d): ord_d = ord(d[0]) if ord_d < 192: slice = d[0] size = ord_d elif 192 <= ord_d < 255: slice = d[:2] #size = size + STN.doubleoct2int(slice) size = STN.doubleoct2int(slice) elif 255 == ord_d: slice = d[:5] #size = size + STN.pentoct2int(slice) size = STN.pentoct2int(slice) len_slice = len(slice) self._d = d[:len_slice + size] type_d = d[len_slice:len_slice + 1] self.type = 127 & ord(type_d) self.critical = 128 & ord(type_d) value_d = d[len_slice + 1:len_slice + size] if SIGSUB_SIGNERID == self.type: self.value = STN.str2hex(value_d[:8]) elif self.type in [SIGSUB_CREATED, SIGSUB_EXPIRES, SIGSUB_KEYEXPIRES]: self.value = STN.str2int(value_d[:4]) self.value = STN.str2int(value_d) elif self.type in [ SIGSUB_EXPORTABLE, SIGSUB_REVOCABLE, SIGSUB_PRIMARYUID ]: self.value = STN.str2int(value_d[:1]) if self.value not in [0, 1]: raise SignatureSubpacketValueError, "Subpacket (# %s) value must be 0 or 1." % ( str(subtype)) elif SIGSUB_TRUST == self.type: # level, amount self.value = (STN.str2int(value_d[0]), STN.str2int(value_d[1])) elif self.type in [ SIGSUB_SYMCODE, SIGSUB_HASHCODE, SIGSUB_COMPCODE, SIGSUB_KEYSERVPREFS, SIGSUB_KEYFLAGS, SIGSUB_FEATURES ]: self.value = [ord(x) for x in value_d] elif SIGSUB_REVOKER == self.type: cls = STN.str2int(value_d[0]) alg = STN.str2int(value_d[1]) fprint = STN.str2hex(value_d[2:22]) self.value = (cls, alg, fprint) elif SIGSUB_NOTE == self.type: flags = [STN.str2int(x) for x in value_d[:4]] # first four flag octs name_len = STN.str2int(value_d[4:6]) val_len = STN.str2int(value_d[6:8]) nam = value_d[8:8 + name_len] val = value_d[8 + name_len:8 + name_len + val_len] self.value = (flags, nam, val) elif self.type in [ SIGSUB_KEYSERV, SIGSUB_POLICYURL, SIGSUB_SIGNERUID, SIGSUB_REGEX ]: self.value = value_d elif SIGSUB_REVOCREASON == self.type: # code, reason self.value = (STN.str2int(value_d[0]), value_d[1:]) elif SIGSUB_SIGTARGET == self.type: raise NotImplementedError, "SIGTARGET not supported" else: # the subpacket has an unknown type, so just pack the data in self.value = value_d
def fill(self, d): ord_d = ord(d[0]) if ord_d < 192: slice = d[0] size = ord_d elif 192 <= ord_d < 255: slice = d[:2] #size = size + STN.doubleoct2int(slice) size = STN.doubleoct2int(slice) elif 255 == ord_d: slice = d[:5] #size = size + STN.pentoct2int(slice) size = STN.pentoct2int(slice) len_slice = len(slice) self._d = d[:len_slice+size] type_d = d[len_slice:len_slice+1] self.type = 127 & ord(type_d) self.critical = 128 & ord(type_d) value_d = d[len_slice+1:len_slice+size] if SIGSUB_SIGNERID == self.type: self.value = STN.str2hex(value_d[:8]) elif self.type in [SIGSUB_CREATED, SIGSUB_EXPIRES, SIGSUB_KEYEXPIRES]: self.value = STN.str2int(value_d[:4]) self.value = STN.str2int(value_d) elif self.type in [SIGSUB_EXPORTABLE, SIGSUB_REVOCABLE, SIGSUB_PRIMARYUID]: self.value = STN.str2int(value_d[:1]) if self.value not in [0, 1]: raise SignatureSubpacketValueError, "Subpacket (# %s) value must be 0 or 1." % (str(subtype)) elif SIGSUB_TRUST == self.type: # level, amount self.value = (STN.str2int(value_d[0]), STN.str2int(value_d[1])) elif self.type in [SIGSUB_SYMCODE, SIGSUB_HASHCODE, SIGSUB_COMPCODE, SIGSUB_KEYSERVPREFS, SIGSUB_KEYFLAGS, SIGSUB_FEATURES]: self.value = [ord(x) for x in value_d] elif SIGSUB_REVOKER == self.type: cls = STN.str2int(value_d[0]) alg = STN.str2int(value_d[1]) fprint = STN.str2hex(value_d[2:22]) self.value = (cls, alg, fprint) elif SIGSUB_NOTE == self.type: flags = [STN.str2int(x) for x in value_d[:4]] # first four flag octs name_len = STN.str2int(value_d[4:6]) val_len = STN.str2int(value_d[6:8]) nam = value_d[8:8+name_len] val = value_d[8+name_len:8+name_len+val_len] self.value = (flags, nam, val) elif self.type in [SIGSUB_KEYSERV, SIGSUB_POLICYURL, SIGSUB_SIGNERUID, SIGSUB_REGEX]: self.value = value_d elif SIGSUB_REVOCREASON == self.type: # code, reason self.value = (STN.str2int(value_d[0]), value_d[1:]) elif SIGSUB_SIGTARGET == self.type: raise NotImplementedError, "SIGTARGET not supported" else: # the subpacket has an unknown type, so just pack the data in self.value = value_d