def _parseIntervalList(s): """Validation functions. Parse a list of comma-separated intervals in the form ((every)? INTERVAL for INTERVAL)|INTERVAL into a list of interval lengths in seconds.""" items = s.strip().lower().split(",") ilist = [] for item in items: item = item.strip() if stringContains(item, " for "): if item.startswith("every "): item = item[6:] interval, duration = item.split(" for ", 1) interval = int(_parseInterval(interval)) duration = int(_parseInterval(duration)) if interval < 1: raise ConfigError("Repeated interval too small in %s" % s) ilist += [interval] * ceilDiv(duration, interval) elif item.startswith("every "): raise ConfigError( "Bad syntax on interval %s. (Did you mean %s for X days?)", item, item) else: interval = int(_parseInterval(item)) ilist.append(interval) return ilist
def _calculateNext(lastAttempt, firstAttempt, retrySchedule, canDrop, now): """DOCDOC""" # If we've never tried to deliver the message, it's ready to # go immediately. if lastAttempt is None: return now # Otherwise, we count from the time the message was first queued, # until we find a scheduled delivery that falls after the last # attempted delivery. # # This scheduled delivery may be in the past. That's okay: it only # means that we've missed a scheduled delivery, and we can try again # immediately. attempt = firstAttempt for interval in retrySchedule: attempt += interval if attempt > lastAttempt: return attempt # Oops: there are no scheduled deliveries after the last delivery. # Time to drop this message, or go into holding mode. if canDrop: return None else: if not retrySchedule or retrySchedule[-1]<5: #DOCDOC retrySchedule = [3600] attempt += (ceilDiv(lastAttempt-attempt+60,retrySchedule[-1]) * retrySchedule[-1]) return attempt
def _parseIntervalList(s): """Validation functions. Parse a list of comma-separated intervals in the form ((every)? INTERVAL for INTERVAL)|INTERVAL into a list of interval lengths in seconds.""" items = s.strip().lower().split(",") ilist = [] for item in items: item = item.strip() if stringContains(item, " for "): if item.startswith("every "): item = item[6:] interval, duration = item.split(" for ", 1) interval = int(_parseInterval(interval)) duration = int(_parseInterval(duration)) if interval < 1: raise ConfigError("Repeated interval too small in %s"%s) ilist += [interval] * ceilDiv(duration, interval) elif item.startswith("every "): raise ConfigError( "Bad syntax on interval %s. (Did you mean %s for X days?)", item, item) else: interval = int(_parseInterval(item)) ilist.append(interval) return ilist
def _calculateNext(lastAttempt, firstAttempt, retrySchedule, canDrop, now): """DOCDOC""" # If we've never tried to deliver the message, it's ready to # go immediately. if lastAttempt is None: return now # Otherwise, we count from the time the message was first queued, # until we find a scheduled delivery that falls after the last # attempted delivery. # # This scheduled delivery may be in the past. That's okay: it only # means that we've missed a scheduled delivery, and we can try again # immediately. attempt = firstAttempt for interval in retrySchedule: attempt += interval if attempt > lastAttempt: return attempt # Oops: there are no scheduled deliveries after the last delivery. # Time to drop this message, or go into holding mode. if canDrop: return None else: if not retrySchedule or retrySchedule[-1] < 5: #DOCDOC retrySchedule = [3600] attempt += (ceilDiv(lastAttempt - attempt + 60, retrySchedule[-1]) * retrySchedule[-1]) return attempt
def _oaep_mgf(seed, bytes): """ Mask generation function specified for RSA-OAEP. Given a seed and a number of bytes, generates a mask for OAEP by computing sha1(seed + "\x00\x00\x00\x00")+sha1(seed+"\x00\x00\x00\x01)+... The mask is truncated to the specified length. LIMITATION: This implementation can only generate 5120 bytes of key material.""" assert bytes <= 5120 padding = [] nHashes = ceilDiv(bytes, DIGEST_LEN) # assert (nHashes-1)*DIGEST_LEN <= bytes <= nHashes*DIGEST_LEN padding = [_ml.sha1("%s\x00\x00\x00%c" % (seed, i)) for i in range(nHashes)] padding = "".join(padding) return padding[:bytes]
def _writeEncryptedFile(fname, password, magic, data): """Write 'data' into an encrypted file named 'fname', replacing it if necessary. Encrypts the data with the password 'password', and uses the filetype 'magic'.""" assert len(magic) == MAGIC_LEN prng = getCommonPRNG() length = struct.pack("!L", len(data)) paddingLen = ceilDiv(len(data), 1024)*1024 - len(data) padding = prng.getBytes(paddingLen) data = "".join([length,data,padding]) salt = prng.getBytes(SALT_LEN) key = sha1(salt+password+salt)[:AES_KEY_LEN] digest = sha1("".join([data,salt,magic])) encrypted = ctr_crypt(data+digest, key) contents = "".join([magic,"\x00",salt,encrypted]) writeFile(fname, armorText(contents, "TYPE III KEYRING", [("Version","0.1")]))
def _writeEncryptedFile(fname, password, magic, data): """Write 'data' into an encrypted file named 'fname', replacing it if necessary. Encrypts the data with the password 'password', and uses the filetype 'magic'.""" assert len(magic) == MAGIC_LEN prng = getCommonPRNG() length = struct.pack("!L", len(data)) paddingLen = ceilDiv(len(data), 1024) * 1024 - len(data) padding = prng.getBytes(paddingLen) data = "".join([length, data, padding]) salt = prng.getBytes(SALT_LEN) key = sha1(salt + password + salt)[:AES_KEY_LEN] digest = sha1("".join([data, salt, magic])) encrypted = ctr_crypt(data + digest, key) contents = "".join([magic, "\x00", salt, encrypted]) writeFile(fname, armorText(contents, "TYPE III KEYRING", [("Version", "0.1")]))
def _oaep_mgf(seed, b): ''' Mask generation function specified for RSA-OAEP. Given a seed and a number of bytes, generates a mask for OAEP by computing sha1(seed + "\x00\x00\x00\x00")+sha1(seed+"\x00\x00\x00\x01)+... The mask is truncated to the specified length. LIMITATION: This implementation can only generate 5120 bytes of key material.''' assert b <= 5120 padding = [] nHashes = ceilDiv(b, DIGEST_LEN) # assert (nHashes-1)*DIGEST_LEN <= b <= nHashes*DIGEST_LEN padding = ([ _ml.sha1("%s\x00\x00\x00%c" % (seed, i)) for i in range(nHashes) ]) padding = "".join(padding) return padding[:b]
def createKeysAsNeeded(self, now=None): """Generate new keys and descriptors as needed, so that the next PUBLICATION_LATENCY+PREPUBLICATION_INTERVAL seconds are covered.""" if now is None: now = time.time() if self.getNextKeygen() > now - 10: # 10 seconds of leeway return if self.keySets: lastExpiry = self.keySets[-1][1] if lastExpiry < now: lastExpiry = now else: lastExpiry = now needToCoverUntil = now + PUBLICATION_LATENCY + PREPUBLICATION_INTERVAL timeToCover = needToCoverUntil - lastExpiry lifetime = self.config['Server']['PublicKeyLifetime'].getSeconds() nKeys = int(ceilDiv(timeToCover, lifetime)) LOG.info("Creating %s keys", nKeys) self.createKeys(num=nKeys)
def createKeysAsNeeded(self,now=None): """Generate new keys and descriptors as needed, so that the next PUBLICATION_LATENCY+PREPUBLICATION_INTERVAL seconds are covered.""" if now is None: now = time.time() if self.getNextKeygen() > now-10: # 10 seconds of leeway return if self.keySets: lastExpiry = self.keySets[-1][1] if lastExpiry < now: lastExpiry = now else: lastExpiry = now needToCoverUntil = now+PUBLICATION_LATENCY+PREPUBLICATION_INTERVAL timeToCover = needToCoverUntil-lastExpiry lifetime = self.config['Server']['PublicKeyLifetime'].getSeconds() nKeys = int(ceilDiv(timeToCover, lifetime)) LOG.info("Creating %s keys", nKeys) self.createKeys(num=nKeys)
def _prng(self, n): reps = ceilDiv(n + self.idx, 256) r = (self.pattern * reps)[self.idx:self.idx + n] self.idx = (self.idx + n) % 256 assert len(r) == n return r
def _prng(self,n): reps = ceilDiv(n+self.idx,256) r = (self.pattern*reps)[self.idx:self.idx+n] self.idx = (self.idx+n) % 256 assert len(r) == n return r