basic functionalty

This commit is contained in:
shim_
2018-04-29 14:11:24 +02:00
commit ee5db19d8e
256 changed files with 48959 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
# -*- coding: ascii -*-
#
# Util/Counter.py : Fast counter for use with CTR-mode ciphers
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Fast counter functions for CTR cipher modes.
CTR is a chaining mode for symmetric block encryption or decryption.
Messages are divideded into blocks, and the cipher operation takes
place on each block using the secret key and a unique *counter block*.
The most straightforward way to fulfil the uniqueness property is
to start with an initial, random *counter block* value, and increment it as
the next block is processed.
The block ciphers from `Crypto.Cipher` (when configured in *MODE_CTR* mode)
invoke a callable object (the *counter* parameter) to get the next *counter block*.
Unfortunately, the Python calling protocol leads to major performance degradations.
The counter functions instantiated by this module will be invoked directly
by the ciphers in `Crypto.Cipher`. The fact that the Python layer is bypassed
lead to more efficient (and faster) execution of CTR cipher modes.
An example of usage is the following:
>>> from Crypto.Cipher import AES
>>> from Crypto.Util import Counter
>>>
>>> pt = b'X'*1000000
>>> ctr = Counter.new(128)
>>> key = b'AES-128 symm key'
>>> cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
>>> ct = cipher.encrypt(pt)
:undocumented: __package__
"""
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
from Crypto.pct_warnings import DisableShortcut_DeprecationWarning
from Crypto.Util import _counter
import struct
import warnings
# Factory function
_deprecated = "deprecated"
def new(nbits, prefix=b(""), suffix=b(""), initial_value=1, overflow=0, little_endian=False, allow_wraparound=False, disable_shortcut=_deprecated):
"""Create a stateful counter block function suitable for CTR encryption modes.
Each call to the function returns the next counter block.
Each counter block is made up by three parts::
prefix || counter value || postfix
The counter value is incremented by 1 at each call.
:Parameters:
nbits : integer
Length of the desired counter, in bits. It must be a multiple of 8.
prefix : byte string
The constant prefix of the counter block. By default, no prefix is
used.
suffix : byte string
The constant postfix of the counter block. By default, no suffix is
used.
initial_value : integer
The initial value of the counter. Default value is 1.
overflow : integer
This value is currently ignored.
little_endian : boolean
If *True*, the counter number will be encoded in little endian format.
If *False* (default), in big endian format.
allow_wraparound : boolean
If *True*, the counter will automatically restart from zero after
reaching the maximum value (``2**nbits-1``).
If *False* (default), the object will raise an *OverflowError*.
disable_shortcut : deprecated
This option is a no-op for backward compatibility. It will be removed
in a future version. Don't use it.
:Returns:
The counter block function.
"""
# Sanity-check the message size
(nbytes, remainder) = divmod(nbits, 8)
if remainder != 0:
# In the future, we might support arbitrary bit lengths, but for now we don't.
raise ValueError("nbits must be a multiple of 8; got %d" % (nbits,))
if nbytes < 1:
raise ValueError("nbits too small")
elif nbytes > 0xffff:
raise ValueError("nbits too large")
initval = _encode(initial_value, nbytes, little_endian)
if disable_shortcut is not _deprecated: # exact object comparison
warnings.warn("disable_shortcut has no effect and is deprecated", DisableShortcut_DeprecationWarning)
if little_endian:
return _counter._newLE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound)
else:
return _counter._newBE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound)
def _encode(n, nbytes, little_endian=False):
retval = []
n = long(n)
for i in range(nbytes):
if little_endian:
retval.append(bchr(n & 0xff))
else:
retval.insert(0, bchr(n & 0xff))
n >>= 8
return b("").join(retval)
# vim:set ts=4 sw=4 sts=4 expandtab:

View File

@@ -0,0 +1,103 @@
#
# -*- coding: utf-8 -*-
#
# Util/Padding.py : Functions to manage padding
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
""" Functions to manage padding
This module provides minimal support for adding and removing standard padding
from data.
"""
__all__ = [ 'PaddingError', 'pad', 'unpad' ]
from Crypto.Util.py3compat import *
class PaddingError(ValueError):
"""Exception raised when padding is incorrect and cannot be removed."""
pass
def pad(data_to_pad, block_size, style='pkcs7'):
"""Apply standard padding.
:Parameters:
data_to_pad : byte string
The data that needs to be padded.
block_size : integer
The block boundary to use for padding. The output length is guaranteed
to be a multiple of ``block_size``.
style : string
Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*.
:Return:
The original data with the appropriate padding added at the end.
"""
padding_len = block_size-len(data_to_pad)%block_size
if style == 'pkcs7':
padding = bchr(padding_len)*padding_len
elif style == 'x923':
padding = bchr(0)*(padding_len-1) + bchr(padding_len)
elif style == 'iso7816':
padding = bchr(128) + bchr(0)*(padding_len-1)
else:
raise ValueError("Unknown padding style")
return data_to_pad + padding
def unpad(padded_data, block_size, style='pkcs7'):
"""Remove standard padding.
:Parameters:
padded_data : byte string
A piece of data with padding that needs to be stripped.
block_size : integer
The block boundary to use for padding. The input length
must be a multiple of ``block_size``.
style : string
Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*.
:Return:
Data without padding.
:Raises PaddingError:
if the padding is incorrect.
"""
pdata_len = len(padded_data)
if pdata_len % block_size:
raise PaddingError("Input data is not padded")
if style in ('pkcs7', 'x923'):
padding_len = bord(padded_data[-1])
if padding_len<1 or padding_len>min(block_size, pdata_len):
raise PaddingError("Padding is incorrect.")
if style == 'pkcs7':
if padded_data[-padding_len:]!=bchr(padding_len)*padding_len:
raise PaddingError("PKCS#7 padding is incorrect.")
else:
if padded_data[-padding_len:-1]!=bchr(0)*(padding_len-1):
raise PaddingError("ANSI X.923 padding is incorrect.")
elif style == 'iso7816':
padding_len = pdata_len - padded_data.rfind(bchr(128))
if padding_len<1 or padding_len>min(block_size, pdata_len):
raise PaddingError("Padding is incorrect.")
if padding_len>1 and padded_data[1-padding_len:]!=bchr(0)*(padding_len-1):
raise PaddingError("ISO 7816-4 padding is incorrect.")
else:
raise ValueError("Unknown padding style")
return padded_data[:-padding_len]

View File

@@ -0,0 +1,364 @@
# rfc1751.py : Converts between 128-bit strings and a human-readable
# sequence of words, as defined in RFC1751: "A Convention for
# Human-Readable 128-bit Keys", by Daniel L. McDonald.
#
# Part of the Python Cryptography Toolkit
#
# Written by Andrew M. Kuchling and others
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
import binascii
from Crypto.Util.py3compat import *
binary={0:'0000', 1:'0001', 2:'0010', 3:'0011', 4:'0100', 5:'0101',
6:'0110', 7:'0111', 8:'1000', 9:'1001', 10:'1010', 11:'1011',
12:'1100', 13:'1101', 14:'1110', 15:'1111'}
def _key2bin(s):
"Convert a key into a string of binary digits"
kl=map(lambda x: bord(x), s)
kl=map(lambda x: binary[x>>4]+binary[x&15], kl)
return ''.join(kl)
def _extract(key, start, length):
"""Extract a bitstring(2.x)/bytestring(2.x) from a string of binary digits, and return its
numeric value."""
k=key[start:start+length]
return reduce(lambda x,y: x*2+ord(y)-48, k, 0)
def key_to_english (key):
"""key_to_english(key:string(2.x)/bytes(3.x)) : string
Transform an arbitrary key into a string containing English words.
The key length must be a multiple of 8.
"""
english=''
for index in range(0, len(key), 8): # Loop over 8-byte subkeys
subkey=key[index:index+8]
# Compute the parity of the key
skbin=_key2bin(subkey) ; p=0
for i in range(0, 64, 2): p=p+_extract(skbin, i, 2)
# Append parity bits to the subkey
skbin=_key2bin(subkey+bchr((p<<6) & 255))
for i in range(0, 64, 11):
english=english+wordlist[_extract(skbin, i, 11)]+' '
return english[:-1] # Remove the trailing space
def english_to_key (s):
"""english_to_key(string):string(2.x)/bytes(2.x)
Transform a string into a corresponding key.
The string must contain words separated by whitespace; the number
of words must be a multiple of 6.
"""
L=s.upper().split() ; key=b('')
for index in range(0, len(L), 6):
sublist=L[index:index+6] ; char=9*[0] ; bits=0
for i in sublist:
index = wordlist.index(i)
shift = (8-(bits+11)%8) %8
y = index << shift
cl, cc, cr = (y>>16), (y>>8)&0xff, y & 0xff
if (shift>5):
char[bits>>3] = char[bits>>3] | cl
char[(bits>>3)+1] = char[(bits>>3)+1] | cc
char[(bits>>3)+2] = char[(bits>>3)+2] | cr
elif shift>-3:
char[bits>>3] = char[bits>>3] | cc
char[(bits>>3)+1] = char[(bits>>3)+1] | cr
else: char[bits>>3] = char[bits>>3] | cr
bits=bits+11
subkey=reduce(lambda x,y:x+bchr(y), char, b(''))
# Check the parity of the resulting key
skbin=_key2bin(subkey)
p=0
for i in range(0, 64, 2): p=p+_extract(skbin, i, 2)
if (p&3) != _extract(skbin, 64, 2):
raise ValueError, "Parity error in resulting key"
key=key+subkey[0:8]
return key
wordlist=[ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT",
"ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET",
"JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT",
"KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB",
"LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE",
"LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT",
"LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG",
"LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW",
"MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT",
"MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG",
"MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED",
"NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD",
"NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF",
"OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL",
"OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT",
"OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD",
"PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG",
"PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT",
"PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB",
"PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT",
"RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM",
"RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB",
"RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM",
"SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET",
"SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY",
"SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY",
"SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN",
"TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE",
"TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP",
"TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP",
"US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS",
"WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT",
"WOK", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE",
"YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT",
"ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS",
"ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE",
"AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA",
"ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN",
"AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW",
"ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA",
"ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM",
"AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL",
"BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM",
"BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK",
"BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH",
"BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT",
"BEAU", "BECK", "BEEF", "BEEN", "BEER",
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN",
"BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE",
"BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE",
"BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT",
"BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK",
"BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT",
"BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK",
"BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS",
"BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD",
"BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG",
"BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST",
"BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF",
"CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL",
"CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL",
"CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF",
"CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG",
"CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA",
"COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN",
"COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK",
"COOL", "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST",
"COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB",
"CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY",
"CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "DADE", "DALE",
"DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DARN",
"DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED",
"DEEM", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK",
"DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", "DINT",
"DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES",
"DOLE", "DOLL", "DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA",
"DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG",
"DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK",
"DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK",
"DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT",
"EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT",
"EMMA", "ENDS", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED",
"FACE", "FACT", "FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL",
"FAME", "FANG", "FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT",
"FEED", "FEEL", "FEET", "FELL", "FELT", "FEND", "FERN", "FEST",
"FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE",
"FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE",
"FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM",
"FOGY", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL",
"FOOT", "FORD", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL",
"FOUR", "FOWL", "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY",
"FROG", "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY",
"FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA",
"GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GARY", "GASH",
"GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE",
"GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN",
"GLIB", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD",
"GOAL", "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG",
"GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB",
"GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN",
"GRIT", "GROW", "GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH",
"GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR",
"HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HANK",
"HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR",
"HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL",
"HELM", "HERB", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN",
"HICK", "HIDE", "HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT",
"HIRE", "HISS", "HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE",
"HOLM", "HOLT", "HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK",
"HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL",
"HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK",
"HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH",
"INTO", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE",
"ITCH", "ITEM", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE",
"JAVA", "JEAN", "JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL",
"JILT", "JIVE", "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN",
"JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY",
"JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST",
"JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "KEEL",
"KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW",
"KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD",
"KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN",
"LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD",
"LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS",
"LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER",
"LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST",
"LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU",
"LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST",
"LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE",
"LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD",
"LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK",
"LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE",
"LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE",
"MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI",
"MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK",
"MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK",
"MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH",
"MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT",
"MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS",
"MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD",
"MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON",
"MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH",
"MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK",
"MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR",
"NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS",
"NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA",
"NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON",
"NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB",
"OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY",
"OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE",
"ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS",
"OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT",
"RAGE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE",
"RASH", "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR",
"RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", "RENA",
"REND", "RENT", "REST", "RICE", "RICH", "RICK", "RIDE", "RIFT",
"RILL", "RIME", "RING", "RINK", "RISE", "RISK", "RITE", "ROAD",
"ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME",
"ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS",
"ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE",
"RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE",
"SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE",
"SANG", "SANK", "SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR",
"SCAT", "SCOT", "SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK",
"SEEM", "SEEN", "SEES", "SELF", "SELL", "SEND", "SENT", "SETS",
"SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN",
"SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE",
"SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW",
"SKID", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY",
"SLED", "SLEW", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT",
"SLOW", "SLUG", "SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB",
"SNOW", "SNUB", "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA",
"SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE",
"SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR",
"STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "SUCH",
"SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM",
"TACK", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK",
"TASK", "TATE", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM",
"TEEN", "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS",
"TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", "THIN",
"THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER",
"TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TINT", "TINY",
"TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG",
"TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG",
"TRIM", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE",
"TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK",
"TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", "USED", "USER",
"USES", "UTAH", "VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST",
"VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY",
"VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE",
"WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK",
"WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY",
"WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR",
"WELD", "WELL", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM",
"WHAT", "WHEE", "WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE",
"WILD", "WILL", "WIND", "WINE", "WING", "WINK", "WINO", "WIRE",
"WISE", "WISH", "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD",
"WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE",
"YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR",
"YELL", "YOGA", "YOKE" ]
if __name__=='__main__':
data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'),
('CCAC2AED591056BE4F90FD441C534766',
'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'),
('EFF81F9BFBC65350920CDD7416DE8009',
'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL')
]
for key, words in data:
print 'Trying key', key
key=binascii.a2b_hex(key)
w2=key_to_english(key)
if w2!=words:
print 'key_to_english fails on key', repr(key), ', producing', str(w2)
k2=english_to_key(words)
if k2!=key:
print 'english_to_key fails on key', repr(key), ', producing', repr(k2)

View File

@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Miscellaneous modules
Contains useful modules that don't belong into any of the
other Crypto.* subpackages.
======================== =============================================
Module Description
======================== =============================================
`Crypto.Util.number` Number-theoretic functions (primality testing, etc.)
`Crypto.Util.Counter` Fast counter functions for CTR cipher modes.
`Crypto.Util.randpool` Random number generation
`Crypto.Util.RFC1751` Converts between 128-bit keys and human-readable
strings of words.
`Crypto.Util.asn1` Minimal support for ASN.1 DER encoding
`Crypto.Util.Padding` Set of functions for adding and removing padding.
======================== =============================================
"""
__all__ = ['randpool', 'RFC1751', 'number', 'strxor', 'asn1', 'Counter',
'Padding' ]
__revision__ = "$Id$"

View File

@@ -0,0 +1,119 @@
# -*- coding: ascii -*-
#
# Util/_number_new.py : utility functions
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
## NOTE: Do not import this module directly. Import these functions from Crypto.Util.number.
__revision__ = "$Id$"
__all__ = ['ceil_shift', 'ceil_div', 'floor_div', 'exact_log2', 'exact_div']
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
def ceil_shift(n, b):
"""Return ceil(n / 2**b) without performing any floating-point or division operations.
This is done by right-shifting n by b bits and incrementing the result by 1
if any '1' bits were shifted out.
"""
if not isinstance(n, (int, long)) or not isinstance(b, (int, long)):
raise TypeError("unsupported operand type(s): %r and %r" % (type(n).__name__, type(b).__name__))
assert n >= 0 and b >= 0 # I haven't tested or even thought about negative values
mask = (1L << b) - 1
if n & mask:
return (n >> b) + 1
else:
return n >> b
def ceil_div(a, b):
"""Return ceil(a / b) without performing any floating-point operations."""
if not isinstance(a, (int, long)) or not isinstance(b, (int, long)):
raise TypeError("unsupported operand type(s): %r and %r" % (type(a).__name__, type(b).__name__))
(q, r) = divmod(a, b)
if r:
return q + 1
else:
return q
def floor_div(a, b):
if not isinstance(a, (int, long)) or not isinstance(b, (int, long)):
raise TypeError("unsupported operand type(s): %r and %r" % (type(a).__name__, type(b).__name__))
(q, r) = divmod(a, b)
return q
def exact_log2(num):
"""Find and return an integer i >= 0 such that num == 2**i.
If no such integer exists, this function raises ValueError.
"""
if not isinstance(num, (int, long)):
raise TypeError("unsupported operand type: %r" % (type(num).__name__,))
n = long(num)
if n <= 0:
raise ValueError("cannot compute logarithm of non-positive number")
i = 0
while n != 0:
if (n & 1) and n != 1:
raise ValueError("No solution could be found")
i += 1
n >>= 1
i -= 1
assert num == (1L << i)
return i
def exact_div(p, d, allow_divzero=False):
"""Find and return an integer n such that p == n * d
If no such integer exists, this function raises ValueError.
Both operands must be integers.
If the second operand is zero, this function will raise ZeroDivisionError
unless allow_divzero is true (default: False).
"""
if not isinstance(p, (int, long)) or not isinstance(d, (int, long)):
raise TypeError("unsupported operand type(s): %r and %r" % (type(p).__name__, type(d).__name__))
if d == 0 and allow_divzero:
n = 0
if p != n * d:
raise ValueError("No solution could be found")
else:
(n, r) = divmod(p, d)
if r != 0:
raise ValueError("No solution could be found")
assert p == n * d
return n
# vim:set ts=4 sw=4 sts=4 expandtab:

View File

@@ -0,0 +1,28 @@
# -*- coding: ascii -*-
#
# _time.py : Internal monotonic time module.
#
# Written in 2013 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
try:
from time import monotonic as maybe_monotonic_time
except ImportError:
from time import time as maybe_monotonic_time

899
modules/Crypto/Util/asn1.py Normal file
View File

@@ -0,0 +1,899 @@
# -*- coding: ascii -*-
#
# Util/asn1.py : Minimal support for ASN.1 DER binary encoding.
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
""" ASN.1 DER encoding and decoding
This module provides minimal support for encoding and decoding `ASN.1`_ DER
objects.
.. _`ASN.1`: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc
"""
from __future__ import nested_scopes
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.py3compat import *
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
from Crypto.Util.py21compat import *
from Crypto.Util.number import long_to_bytes, bytes_to_long
__all__ = [ 'DerObject', 'DerInteger', 'DerOctetString', 'DerNull',
'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf',
'newDerInteger', 'newDerOctetString', 'newDerSequence',
'newDerObjectId', 'newDerBitString', 'newDerSetOf' ]
def _isInt(x, onlyNonNegative=False):
test = 0
try:
test += x
except TypeError:
return False
return not onlyNonNegative or x>=0
class BytesIO_EOF(BytesIO):
"""This class differs from BytesIO in that an EOFError exception is
raised whenever EOF is reached."""
def __init__(self, *params):
BytesIO.__init__(self, *params)
self.setRecord(False)
def setRecord(self, record):
self._record = record
self._recording = b("")
def read(self, length):
s = BytesIO.read(self, length)
if len(s)<length:
raise EOFError
if self._record:
self._recording += s
return s
def read_byte(self):
return self.read(1)[0]
class NoDerElementError(EOFError):
pass
class DerObject(object):
"""Base class for defining a single DER object.
This class should never be directly instantiated.
"""
def __init__(self, asn1Id=None, payload=b(''), implicit=None, constructed=False):
"""Initialize the DER object according to a specific ASN.1 type.
:Parameters:
asn1Id : integer
The universal DER tag identifier for this object
(e.g. 0x10 for a SEQUENCE). If None, the tag is not known
yet.
payload : byte string
The initial payload of the object.
If not specified, the payload is empty.
implicit : integer
The IMPLICIT tag to use for the encoded object.
It overrides the universal tag *asn1Id*.
constructed : bool
True when the ASN.1 type is *constructed*.
False when it is *primitive*.
"""
if asn1Id==None:
self._idOctet = None
return
asn1Id = self._convertTag(asn1Id)
self._implicit = implicit
if implicit:
# In a BER/DER identifier octet:
# * bits 4-0 contain the tag value
# * bit 5 is set if the type is 'construted'
# and unset if 'primitive'
# * bits 7-6 depend on the encoding class
#
# Class | Bit 7, Bit 6
# universal | 0 0
# application | 0 1
# context-spec | 1 0 (default for IMPLICIT)
# private | 1 1
#
self._idOctet = 0x80 | self._convertTag(implicit)
else:
self._idOctet = asn1Id
if constructed:
self._idOctet |= 0x20
self.payload = payload
def _convertTag(self, tag):
"""Check if *tag* is a real DER tag.
Convert it from a character to number if necessary.
"""
if not _isInt(tag):
if len(tag)==1:
tag = bord(tag[0])
# Ensure that tag is a low tag
if not (_isInt(tag) and 0 <= tag < 0x1F):
raise ValueError("Wrong DER tag")
return tag
def _lengthOctets(self):
"""Build length octets according to the current object's payload.
Return a byte string that encodes the payload length (in
bytes) in a format suitable for DER length octets (L).
"""
payloadLen = len(self.payload)
if payloadLen>127:
encoding = long_to_bytes(payloadLen)
return bchr(len(encoding)+128) + encoding
return bchr(payloadLen)
def encode(self):
"""Return this DER element, fully encoded as a binary byte string."""
# Concatenate identifier octets, length octets,
# and contents octets
return bchr(self._idOctet) + self._lengthOctets() + self.payload
def _decodeLen(self, s):
"""Decode DER length octets from a file."""
length = bord(s.read_byte())
if length<=127:
return length
payloadLength = bytes_to_long(s.read(length & 0x7F))
# According to DER (but not BER) the long form is used
# only when the length doesn't fit into 7 bits.
if payloadLength<=127:
raise ValueError("Not a DER length tag (but still valid BER).")
return payloadLength
def decode(self, derEle):
"""Decode a complete DER element, and re-initializes this
object with it.
:Parameters:
derEle : byte string
A complete DER element.
:Raise ValueError:
In case of parsing errors.
:Raise EOFError:
If the DER element is too short.
"""
s = BytesIO_EOF(derEle)
self._decodeFromStream(s)
# There shouldn't be other bytes left
try:
b = s.read_byte()
raise ValueError("Unexpected extra data after the DER structure")
except EOFError:
pass
def _decodeFromStream(self, s):
"""Decode a complete DER element from a file."""
try:
idOctet = bord(s.read_byte())
except EOFError:
raise NoDerElementError
if self._idOctet != None:
if idOctet != self._idOctet:
raise ValueError("Unexpected DER tag")
else:
self._idOctet = idOctet
length = self._decodeLen(s)
self.payload = s.read(length)
class DerInteger(DerObject):
"""Class to model a DER INTEGER.
An example of encoding is:
>>> from Crypto.Util.asn1 import DerInteger
>>> from binascii import hexlify, unhexlify
>>> int_der = DerInteger(9)
>>> print hexlify(int_der.encode())
which will show ``020109``, the DER encoding of 9.
And for decoding:
>>> s = unhexlify(b'020109')
>>> try:
>>> int_der = DerInteger()
>>> int_der.decode(s)
>>> print int_der.value
>>> except (ValueError, EOFError):
>>> print "Not a valid DER INTEGER"
the output will be ``9``.
"""
def __init__(self, value=0, implicit=None):
"""Initialize the DER object as an INTEGER.
:Parameters:
value : integer
The value of the integer.
implicit : integer
The IMPLICIT tag to use for the encoded object.
It overrides the universal tag for INTEGER (2).
"""
DerObject.__init__(self, 0x02, b(''), implicit, False)
self.value = value #: The integer value
def encode(self):
"""Return the DER INTEGER, fully encoded as a
binary string."""
number = self.value
self.payload = b('')
while True:
self.payload = bchr(number&255) + self.payload
if 128 <= number <= 255:
self.payload = bchr(0x00) + self.payload
if -128 <= number <= 255:
break
number >>= 8
return DerObject.encode(self)
def decode(self, derEle):
"""Decode a complete DER INTEGER DER, and re-initializes this
object with it.
:Parameters:
derEle : byte string
A complete INTEGER DER element.
:Raise ValueError:
In case of parsing errors.
:Raise EOFError:
If the DER element is too short.
"""
DerObject.decode(self, derEle)
def _decodeFromStream(self, s):
"""Decode a complete DER INTEGER from a file."""
# Fill up self.payload
DerObject._decodeFromStream(self, s)
# Derive self.value from self.payload
self.value = 0L
bits = 1
for i in self.payload:
self.value *= 256
self.value += bord(i)
bits <<= 8
if self.payload and bord(self.payload[0]) & 0x80:
self.value -= bits
def newDerInteger(number):
"""Create a DerInteger object, already initialized with an integer."""
der = DerInteger(number)
return der
class DerSequence(DerObject):
"""Class to model a DER SEQUENCE.
This object behaves like a dynamic Python sequence.
Sub-elements that are INTEGERs behave like Python integers.
Any other sub-element is a binary string encoded as a complete DER
sub-element (TLV).
An example of encoding is:
>>> from Crypto.Util.asn1 import DerSequence, DerInteger
>>> from binascii import hexlify, unhexlify
>>> obj_der = unhexlify('070102')
>>> seq_der = DerSequence([4])
>>> seq_der.append(9)
>>> seq_der.append(obj_der.encode())
>>> print hexlify(seq_der.encode())
which will show ``3009020104020109070102``, the DER encoding of the
sequence containing ``4``, ``9``, and the object with payload ``02``.
For decoding:
>>> s = unhexlify(b'3009020104020109070102')
>>> try:
>>> seq_der = DerSequence()
>>> seq_der.decode(s)
>>> print len(seq_der)
>>> print seq_der[0]
>>> print seq_der[:]
>>> except (ValueError, EOFError):
>>> print "Not a valid DER SEQUENCE"
the output will be::
3
4
[4L, 9L, b'\x07\x01\x02']
"""
def __init__(self, startSeq=None, implicit=None):
"""Initialize the DER object as a SEQUENCE.
:Parameters:
startSeq : Python sequence
A sequence whose element are either integers or
other DER objects.
implicit : integer
The IMPLICIT tag to use for the encoded object.
It overrides the universal tag for SEQUENCE (16).
"""
DerObject.__init__(self, 0x10, b(''), implicit, True)
if startSeq==None:
self._seq = []
else:
self._seq = startSeq
## A few methods to make it behave like a python sequence
def __delitem__(self, n):
del self._seq[n]
def __getitem__(self, n):
return self._seq[n]
def __setitem__(self, key, value):
self._seq[key] = value
def __setslice__(self,i,j,sequence):
self._seq[i:j] = sequence
def __delslice__(self,i,j):
del self._seq[i:j]
def __getslice__(self, i, j):
return self._seq[max(0, i):max(0, j)]
def __len__(self):
return len(self._seq)
def __iadd__(self, item):
self._seq.append(item)
return self
def append(self, item):
self._seq.append(item)
return self
def hasInts(self, onlyNonNegative=True):
"""Return the number of items in this sequence that are
integers.
:Parameters:
onlyNonNegative : boolean
If True, negative integers are not counted in.
"""
def _isInt2(x):
return _isInt(x, onlyNonNegative)
return len(filter(_isInt2, self._seq))
def hasOnlyInts(self, onlyNonNegative=True):
"""Return True if all items in this sequence are integers
or non-negative integers.
This function returns False is the sequence is empty,
or at least one member is not an integer.
:Parameters:
onlyNonNegative : boolean
If True, the presence of negative integers
causes the method to return False."""
return self._seq and self.hasInts(onlyNonNegative)==len(self._seq)
def encode(self):
"""Return this DER SEQUENCE, fully encoded as a
binary string.
:Raises ValueError:
If some elements in the sequence are neither integers
nor byte strings.
"""
self.payload = b('')
for item in self._seq:
try:
self.payload += item
except TypeError:
try:
self.payload += DerInteger(item).encode()
except TypeError:
raise ValueError("Trying to DER encode an unknown object")
return DerObject.encode(self)
def decode(self, derEle):
"""Decode a complete DER SEQUENCE, and re-initializes this
object with it.
:Parameters:
derEle : byte string
A complete SEQUENCE DER element.
:Raise ValueError:
In case of parsing errors.
:Raise EOFError:
If the DER element is too short.
DER INTEGERs are decoded into Python integers. Any other DER
element is not decoded. Its validity is not checked.
"""
DerObject.decode(self, derEle)
def _decodeFromStream(self, s):
"""Decode a complete DER SEQUENCE from a file."""
self._seq = []
# Fill up self.payload
DerObject._decodeFromStream(self, s)
# Add one item at a time to self.seq, by scanning self.payload
p = BytesIO_EOF(self.payload)
while True:
try:
p.setRecord(True)
der = DerObject()
der._decodeFromStream(p)
# Parse INTEGERs differently
if der._idOctet != 0x02:
self._seq.append(p._recording)
else:
derInt = DerInteger()
derInt.decode(p._recording)
self._seq.append(derInt.value)
except NoDerElementError:
break
# end
def newDerSequence(*der_objs):
"""Create a DerSequence object, already initialized with all objects
passed as parameters."""
der = DerSequence()
for obj in der_objs:
if isinstance(obj, DerObject):
der += obj.encode()
else:
der += obj
return der
class DerOctetString(DerObject):
"""Class to model a DER OCTET STRING.
An example of encoding is:
>>> from Crypto.Util.asn1 import DerOctetString
>>> from binascii import hexlify, unhexlify
>>> os_der = DerOctetString(b'\\xaa')
>>> os_der.payload += b'\\xbb'
>>> print hexlify(os_der.encode())
which will show ``0402aabb``, the DER encoding for the byte string
``b'\\xAA\\xBB'``.
For decoding:
>>> s = unhexlify(b'0402aabb')
>>> try:
>>> os_der = DerOctetString()
>>> os_der.decode(s)
>>> print hexlify(os_der.payload)
>>> except (ValueError, EOFError):
>>> print "Not a valid DER OCTET STRING"
the output will be ``aabb``.
"""
def __init__(self, value=b(''), implicit=None):
"""Initialize the DER object as an OCTET STRING.
:Parameters:
value : byte string
The initial payload of the object.
If not specified, the payload is empty.
implicit : integer
The IMPLICIT tag to use for the encoded object.
It overrides the universal tag for OCTET STRING (4).
"""
DerObject.__init__(self, 0x04, value, implicit, False)
def newDerOctetString(binstring):
"""Create a DerOctetString object, already initialized with the binary
string."""
if isinstance(binstring, DerObject):
der = DerOctetString(binstring.encode())
else:
der = DerOctetString(binstring)
return der
class DerNull(DerObject):
"""Class to model a DER NULL element."""
def __init__(self):
"""Initialize the DER object as a NULL."""
DerObject.__init__(self, 0x05, b(''), False)
class DerObjectId(DerObject):
"""Class to model a DER OBJECT ID.
An example of encoding is:
>>> from Crypto.Util.asn1 import DerObjectId
>>> from binascii import hexlify, unhexlify
>>> oid_der = DerObjectId("1.2")
>>> oid_der.value += ".840.113549.1.1.1"
>>> print hexlify(oid_der.encode())
which will show ``06092a864886f70d010101``, the DER encoding for the
RSA Object Identifier ``1.2.840.113549.1.1.1``.
For decoding:
>>> s = unhexlify(b'06092a864886f70d010101')
>>> try:
>>> oid_der = DerObjectId()
>>> oid_der.decode(s)
>>> print oid_der.value
>>> except (ValueError, EOFError):
>>> print "Not a valid DER OBJECT ID"
the output will be ``1.2.840.113549.1.1.1``.
"""
def __init__(self, value='', implicit=None):
"""Initialize the DER object as an OBJECT ID.
:Parameters:
value : string
The initial Object Identifier (e.g. "1.2.0.0.6.2").
implicit : integer
The IMPLICIT tag to use for the encoded object.
It overrides the universal tag for OBJECT ID (6).
"""
DerObject.__init__(self, 0x06, b(''), implicit, False)
self.value = value #: The Object ID, a dot separated list of integers
def encode(self):
"""Return the DER OBJECT ID, fully encoded as a
binary string."""
comps = map(int,self.value.split("."))
if len(comps)<2:
raise ValueError("Not a valid Object Identifier string")
self.payload = bchr(40*comps[0]+comps[1])
for v in comps[2:]:
enc = []
while v:
enc.insert(0, (v & 0x7F) | 0x80)
v >>= 7
enc[-1] &= 0x7F
self.payload += b('').join(map(bchr, enc))
return DerObject.encode(self)
def decode(self, derEle):
"""Decode a complete DER OBJECT ID, and re-initializes this
object with it.
:Parameters:
derEle : byte string
A complete DER OBJECT ID.
:Raise ValueError:
In case of parsing errors.
:Raise EOFError:
If the DER element is too short.
"""
DerObject.decode(self, derEle)
def _decodeFromStream(self, s):
"""Decode a complete DER OBJECT ID from a file."""
# Fill up self.payload
DerObject._decodeFromStream(self, s)
# Derive self.value from self.payload
p = BytesIO_EOF(self.payload)
comps = list(map(str, divmod(bord(p.read_byte()),40)))
v = 0
try:
while True:
c = p.read_byte()
v = v*128 + (bord(c) & 0x7F)
if not (bord(c) & 0x80):
comps.append(str(v))
v = 0
except EOFError:
pass
self.value = '.'.join(comps)
def newDerObjectId(dottedstring):
"""Create a DerObjectId object, already initialized with the given Object
Identifier (a dotted string)."""
der = DerObjectId(dottedstring)
return der
class DerBitString(DerObject):
"""Class to model a DER BIT STRING.
An example of encoding is:
>>> from Crypto.Util.asn1 import DerBitString
>>> from binascii import hexlify, unhexlify
>>> bs_der = DerBitString(b'\\xaa')
>>> bs_der.value += b'\\xbb'
>>> print hexlify(bs_der.encode())
which will show ``040300aabb``, the DER encoding for the bit string
``b'\\xAA\\xBB'``.
For decoding:
>>> s = unhexlify(b'040300aabb')
>>> try:
>>> bs_der = DerBitString()
>>> bs_der.decode(s)
>>> print hexlify(bs_der.value)
>>> except (ValueError, EOFError):
>>> print "Not a valid DER OCTET STRING"
the output will be ``aabb``.
"""
def __init__(self, value=b(''), implicit=None):
"""Initialize the DER object as a BIT STRING.
:Parameters:
value : byte string
The initial, packed bit string.
If not specified, the bit string is empty.
implicit : integer
The IMPLICIT tag to use for the encoded object.
It overrides the universal tag for OCTET STRING (3).
"""
DerObject.__init__(self, 0x03, b(''), implicit, False)
self.value = value #: The bitstring value (packed)
def encode(self):
"""Return the DER BIT STRING, fully encoded as a
binary string."""
# Add padding count byte
self.payload = b('\x00') + self.value
return DerObject.encode(self)
def decode(self, derEle):
"""Decode a complete DER BIT STRING, and re-initializes this
object with it.
:Parameters:
derEle : byte string
A complete DER BIT STRING.
:Raise ValueError:
In case of parsing errors.
:Raise EOFError:
If the DER element is too short.
"""
DerObject.decode(self, derEle)
def _decodeFromStream(self, s):
"""Decode a complete DER BIT STRING DER from a file."""
# Fill-up self.payload
DerObject._decodeFromStream(self, s)
if self.payload and bord(self.payload[0])!=0:
raise ValueError("Not a valid BIT STRING")
# Fill-up self.value
self.value = b('')
# Remove padding count byte
if self.payload:
self.value = self.payload[1:]
def newDerBitString(binstring):
"""Create a DerStringString object, already initialized with the binary
string."""
if isinstance(binstring, DerObject):
der = DerBitString(binstring.encode())
else:
der = DerBitString(binstring)
return der
class DerSetOf(DerObject):
"""Class to model a DER SET OF.
An example of encoding is:
>>> from Crypto.Util.asn1 import DerBitString
>>> from binascii import hexlify, unhexlify
>>> so_der = DerSetOf([4,5])
>>> so_der.add(6)
>>> print hexlify(so_der.encode())
which will show ``3109020104020105020106``, the DER encoding
of a SET OF with items 4,5, and 6.
For decoding:
>>> s = unhexlify(b'3109020104020105020106')
>>> try:
>>> so_der = DerSetOf()
>>> so_der.decode(s)
>>> print [x for x in so_der]
>>> except (ValueError, EOFError):
>>> print "Not a valid DER SET OF"
the output will be ``[4L, 5L, 6L]``.
"""
def __init__(self, startSet=None, implicit=None):
"""Initialize the DER object as a SET OF.
:Parameters:
startSet : container
The initial set of integers or DER encoded objects.
implicit : integer
The IMPLICIT tag to use for the encoded object.
It overrides the universal tag for SET OF (17).
"""
DerObject.__init__(self, 0x11, b(''), implicit, True)
self._seq = []
self._elemOctet = None
if startSet:
for e in startSet:
self.add(e)
def __getitem__(self, n):
return self._seq[n]
def __iter__(self):
return iter(self._seq)
def __len__(self):
return len(self._seq)
def add(self, elem):
"""Add an element to the set.
:Parameters:
elem : byte string or integer
An element of the same type of objects already in the set.
It can be an integer or a DER encoded object.
"""
if _isInt(elem):
eo = 0x02
else:
eo = bord(elem[0])
if self._elemOctet != eo:
if self._elemOctet:
raise ValueError("New element does not belong to the set")
self._elemOctet = eo
if not elem in self._seq:
self._seq.append(elem)
def decode(self, derEle):
"""Decode a complete SET OF DER element, and re-initializes this
object with it.
DER INTEGERs are decoded into Python integers. Any other DER
element is left undecoded; its validity is not checked.
:Parameters:
derEle : byte string
A complete DER BIT SET OF.
:Raise ValueError:
In case of parsing errors.
:Raise EOFError:
If the DER element is too short.
"""
DerObject.decode(self, derEle)
def _decodeFromStream(self, s):
"""Decode a complete DER SET OF from a file."""
self._seq = []
# Fill up self.payload
DerObject._decodeFromStream(self, s)
# Add one item at a time to self.seq, by scanning self.payload
p = BytesIO_EOF(self.payload)
setIdOctet = -1
while True:
try:
p.setRecord(True)
der = DerObject()
der._decodeFromStream(p)
# Verify that all members are of the same type
if setIdOctet < 0:
setIdOctet = der._idOctet
else:
if setIdOctet != der._idOctet:
raise ValueError("Not all elements are of the same DER type")
# Parse INTEGERs differently
if setIdOctet != 0x02:
self._seq.append(p._recording)
else:
derInt = DerInteger()
derInt.decode(p._recording)
self._seq.append(derInt.value)
except NoDerElementError:
break
# end
def encode(self):
"""Return this SET OF DER element, fully encoded as a
binary string.
"""
# Elements in the set must be ordered in lexicographic order
ordered = []
for item in self._seq:
if _isInt(item):
bys = DerInteger(item).encode()
else:
bys = item
ordered.append(bys)
ordered.sort()
self.payload = b('').join(ordered)
return DerObject.encode(self)
def newDerSetOf(*der_objs):
"""Create a DerSequence object, already initialized with all objects
passed as parameters."""
der = DerSetOf()
for obj in der_objs:
if isinstance(obj, DerObject):
der.add(obj.encode())
else:
der.add(obj)
return der

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
#
# Util/py21compat.py : Compatibility code for Python 2.1
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Compatibility code for Python 2.1
Currently, this just defines:
- True and False
- object
- isinstance
"""
__revision__ = "$Id$"
__all__ = []
import sys
import __builtin__
# 'True' and 'False' aren't defined in Python 2.1. Define them.
try:
True, False
except NameError:
(True, False) = (1, 0)
__all__ += ['True', 'False']
# New-style classes were introduced in Python 2.2. Defining "object" in Python
# 2.1 lets us use new-style classes in versions of Python that support them,
# while still maintaining backward compatibility with old-style classes
try:
object
except NameError:
class object: pass
__all__ += ['object']
# Starting with Python 2.2, isinstance allows a tuple for the second argument.
# Also, builtins like "tuple", "list", "str", "unicode", "int", and "long"
# became first-class types, rather than functions. We want to support
# constructs like:
# isinstance(x, (int, long))
# So we hack it for Python 2.1.
try:
isinstance(5, (int, long))
except TypeError:
__all__ += ['isinstance']
_builtin_type_map = {
tuple: type(()),
list: type([]),
str: type(""),
unicode: type(u""),
int: type(0),
long: type(0L),
}
def isinstance(obj, t):
if not __builtin__.isinstance(t, type(())):
# t is not a tuple
return __builtin__.isinstance(obj, _builtin_type_map.get(t, t))
else:
# t is a tuple
for typ in t:
if __builtin__.isinstance(obj, _builtin_type_map.get(typ, typ)):
return True
return False
#
# Python 2.2 introduces the built-in staticmethod(). Python 2.4 turns
# it into a function decorator (@staticmethod).
#
# The following recipe for achieving the same thing in Python 2.1 comes
# from the Python Cookbok ("Implementanting Static Methods").
#
try:
class A:
def a(): pass
a = staticmethod(a)
except NameError:
class staticmethod:
def __init__(self, anycallable):
self.__call__ = anycallable
__all__ += ['staticmethod']
# vim:set ts=4 sw=4 sts=4 expandtab:

View File

@@ -0,0 +1,117 @@
# -*- coding: utf-8 -*-
#
# Util/py3compat.py : Compatibility code for handling Py3k / Python 2.x
#
# Written in 2010 by Thorsten Behrens
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""Compatibility code for handling string/bytes changes from Python 2.x to Py3k
In Python 2.x, strings (of type ''str'') contain binary data, including encoded
Unicode text (e.g. UTF-8). The separate type ''unicode'' holds Unicode text.
Unicode literals are specified via the u'...' prefix. Indexing or slicing
either type always produces a string of the same type as the original.
Data read from a file is always of '''str'' type.
In Python 3.x, strings (type ''str'') may only contain Unicode text. The u'...'
prefix and the ''unicode'' type are now redundant. A new type (called
''bytes'') has to be used for binary data (including any particular
''encoding'' of a string). The b'...' prefix allows one to specify a binary
literal. Indexing or slicing a string produces another string. Slicing a byte
string produces another byte string, but the indexing operation produces an
integer. Data read from a file is of '''str'' type if the file was opened in
text mode, or of ''bytes'' type otherwise.
Since PyCrypto aims at supporting both Python 2.x and 3.x, the following helper
functions are used to keep the rest of the library as independent as possible
from the actual Python version.
In general, the code should always deal with binary strings, and use integers
instead of 1-byte character strings.
b(s)
Take a text string literal (with no prefix or with u'...' prefix) and
make a byte string.
bchr(c)
Take an integer and make a 1-character byte string.
bord(c)
Take the result of indexing on a byte string and make an integer.
tobytes(s)
Take a text string, a byte string, or a sequence of character taken from
a byte string and make a byte string.
"""
__revision__ = "$Id$"
import sys
if sys.version_info[0] == 2:
def b(s):
return s
def bchr(s):
return chr(s)
def bstr(s):
return str(s)
def bord(s):
return ord(s)
if sys.version_info[1] == 1:
def tobytes(s):
try:
return s.encode('latin-1')
except:
return ''.join(s)
def tostr(bs):
return unicode(bs, 'latin-1')
else:
def tobytes(s):
if isinstance(s, unicode):
return s.encode("latin-1")
else:
return ''.join(s)
def tostr(bs):
return bs.decode('latin-1')
# In Pyton 2.x, StringIO is a stand-alone module
from StringIO import StringIO as BytesIO
else:
def b(s):
return s.encode("latin-1") # utf-8 would cause some side-effects we don't want
def bchr(s):
return bytes([s])
def bstr(s):
if isinstance(s,str):
return bytes(s,"latin-1")
else:
return bytes(s)
def bord(s):
return s
def tobytes(s):
if isinstance(s,bytes):
return s
else:
if isinstance(s,str):
return s.encode("latin-1")
else:
return bytes(s)
def tostr(bs):
return bs.decode("latin-1")
# In Pyton 3.x, StringIO is a sub-module of io
from io import BytesIO
# vim:set ts=4 sw=4 sts=4 expandtab:

View File

@@ -0,0 +1,82 @@
#
# randpool.py : Cryptographically strong random number generation
#
# Part of the Python Cryptography Toolkit
#
# Written by Andrew M. Kuchling, Mark Moraes, and others
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
#
__revision__ = "$Id$"
from Crypto.pct_warnings import RandomPool_DeprecationWarning
import Crypto.Random
import warnings
class RandomPool:
"""Deprecated. Use Random.new() instead.
See http://www.pycrypto.org/randpool-broken
"""
def __init__(self, numbytes = 160, cipher=None, hash=None, file=None):
warnings.warn("This application uses RandomPool, which is BROKEN in older releases. See http://www.pycrypto.org/randpool-broken",
RandomPool_DeprecationWarning)
self.__rng = Crypto.Random.new()
self.bytes = numbytes
self.bits = self.bytes * 8
self.entropy = self.bits
def get_bytes(self, N):
return self.__rng.read(N)
def _updateEntropyEstimate(self, nbits):
self.entropy += nbits
if self.entropy < 0:
self.entropy = 0
elif self.entropy > self.bits:
self.entropy = self.bits
def _randomize(self, N=0, devname="/dev/urandom"):
"""Dummy _randomize() function"""
self.__rng.flush()
def randomize(self, N=0):
"""Dummy randomize() function"""
self.__rng.flush()
def stir(self, s=''):
"""Dummy stir() function"""
self.__rng.flush()
def stir_n(self, N=3):
"""Dummy stir_n() function"""
self.__rng.flush()
def add_event(self, s=''):
"""Dummy add_event() function"""
self.__rng.flush()
def getBytes(self, N):
"""Dummy getBytes() function"""
return self.get_bytes(N)
def addEvent(self, event, s=""):
"""Dummy addEvent() function"""
return self.add_event()

View File

@@ -0,0 +1,28 @@
#
# Util/winrandom.py : Stub for Crypto.Random.OSRNG.winrandom
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
__revision__ = "$Id$"
from Crypto.Random.OSRNG.winrandom import *
# vim:set ts=4 sw=4 sts=4 expandtab: