コード例 #1
0
ファイル: pkt.py プロジェクト: BackupTheBerlios/pgpyp-svn
    def get_fprint(self):
        """Get a key's fingerprint as an uppercase hex string.
        """
        if 3 == self.version:
            import md5

            n_bytes = mpi2str([self.mpi[0]],
                              None)[2:]  # chop off MPI length bytes
            e_bytes = mpi2str([self.mpi[1]], None)[2:]

            return md5.new(''.join([n_bytes, e_bytes])).hexdigest().upper()

        elif 4 == self.version:
            import sha
            f_data = ''.join([
                int2str(self.version),  #self._val2str('version'),
                int2str(self.created),  #self._val2str('created'),
                int2str(self.k_asym),  #self._val2str('k_asym'),
                mpi2str(self.mpi, None)
            ])  #self._val2str('mpi')])
            len_f_data = len(f_data)
            hi = chr((0xffff & len_f_data) >> 8)  # high order packet length
            lo = chr(0xff & len_f_data)  # low order packet length

            f = ['\x99', hi, lo, f_data]
            return sha.new(''.join(f)).hexdigest().upper()
コード例 #2
0
def create_SymmetricKeyEncryptedSessionKeyBody(*args, **kwords):
    """Create a SymmetricKeyEncryptedSessionKeyBody instance.

    :Parameters:
        - `args`: parameter list
        - `kwords`: keyword parameter list

    Keyword options:
        - `alg`: integer symmetric key algorithm
        - `s2k`: `OpenPGP.packet.S2K` instance
        - `version`: optional integer version number (default 4)

    :Returns: `SymmetricKeyEncryptedSessionKeyBody` instance
    """
    try:
        kwords = args[0]
    except IndexError:
        pass

    if 'version' in kwords:
        if 0 < version < 128:
            version = kwords['version']
        else:
            raise PGPValueError, "Symmetric session key version %s is out of range." % version
    else:
        version = 4

    d = []
    d.append(STN.int2str(version)[0])
    d.append(STN.int2str(kwords['alg'])[0])
    d.append(kwords['s2k']._d)
    return SymmetricKeyEncryptedSessionKeyBody(''.join(d))
コード例 #3
0
ファイル: pkt.py プロジェクト: BackupTheBerlios/pgpyp-svn
def mpi2str(l, limit):
    """Convert a list of MPIs to a byte-string.

    :Parameters:
        - `l`: list of MPI integers
        - `limit`: dummy parameter to follow svt_*() suit

    :Returns: MPI byte-string

    :note: This should probably return some sort of an index like `str2mpi()`
        since a limit < len(l) might be useful. But it's not useful now.
    """
    d = []

    for i in l:
        i_d = int2str(i)
        i_length = len(i_d)
        bit_count = sigbits(i_d[0]) + (8 * (i_length - 1))
        i_length_str = int2str(bit_count)

        if 2 < len(i_length_str):
            raise ValueError, "MPI integer > two octs: %s octets used>" % str(
                i_length)

        elif 1 == len(i_length_str):
            i_length_str = ''.join(['\x00', i_length_str])

        d.append(''.join([i_length_str,
                          i_d]))  # since limit checks complete mpi

        if limit == len(d):
            break

    return ''.join(d)
コード例 #4
0
def create_MPI(i):
    """Create an MPI out of an integer.

    :Parameters:
        - `i`: integer

    :Returns: `MPI` instance
    """
    d = []
    i_d = STN.int2str(i)
    i_length = len(i_d)
    bit_count = STN.sigbits(i_d[0]) + (8 * (i_length - 1))
    i_length_str = STN.int2str(bit_count)

    if 2 < len(i_length_str):
        raise ValueError, "int is larger than two octets can specify - int occupies %s octets" % str(
            i_length)

    elif 1 == len(i_length_str):
        i_length_str = ''.join(['\x00', i_length_str])

    d.append(i_length_str)
    d.append(i_d)

    return MPI(''.join(d))
コード例 #5
0
ファイル: crypto.py プロジェクト: Ando02/wubiuefi
def decrypt_public(algorithm, key_tuple, cipher_tuple):
    """Decrypt public key encrypted data.

    :Parameters:
        - `algorithm`: integer public key algorithm constant
        - `key_tuple`: tuple containing a public and private integers of the
          target key, RSA values (n, d) or ElGamal values (p, x)
        - `cipher_tuple`: tuple containing the integers of the encrypted data,
          coerced RSA value (c, ) and ElGamal values (a, b)

    :Returns: string cleartext

    `decrypt_public()` works with public key encrypted information (information
    encrypted to public key values and decrypted using the corresponding secret
    key values). This function works with tuples of public key values and
    tuples of values that comprise the "ciphertext."

    **Use this function to decrypt public key encrypted session key packets.**

    RSA key tuple (n, d):
        - `n`: integer RSA product of primes p & q
        - `d`: integer RSA decryption key

    RSA cipher tuple (c, ):
        - `c`: integer m**e mod n

    ElGamal key tuple (p, x):
        - `p`: integer ElGamal prime
        - `x`: integer ElGamal private key

    ElGamal cipher tuple (a, b):
        - `a`: integer ElGamal value g**k mod p
        - `b`: integer ElGamal value m * y**k mod p

    Use this for decrypting public-key encrypted session keys.
    """
    key_tuple = tuple([long(i) for i in key_tuple]) # long(): fastmath dep

    if algorithm in [ASYM_RSA_EOS, ASYM_RSA_E]:
        from Crypto.PublicKey import RSA

        key = RSA.construct((key_tuple[0], 0L, key_tuple[1])) # L for fastmath
        a = STN.int2str(cipher_tuple[0])
        return key.decrypt((a,))

    elif algorithm in [ASYM_ELGAMAL_EOS, ASYM_ELGAMAL_E]:
        from Crypto.PublicKey import ElGamal

        key = ElGamal.construct((key_tuple[0], 0, 0, key_tuple[1]))
        a = STN.int2str(cipher_tuple[0])
        b = STN.int2str(cipher_tuple[1])
        return key.decrypt((a, b))

    else:
        raise NotImplementedError, "Unsupported asymmetric algorithm:%s" % algorithm
コード例 #6
0
ファイル: S2K.py プロジェクト: Zaryob/wubi
def create_S2K(*args, **kwords):
    """Create an S2K (string-to-key specifier) instance.
    
    :Parameters:
        - `args`: parameter list
        - `kwords`: keyword parameter dictionary 

    :Keywords:
        - `alg_hash`: integer hash algorithm constant (default SHA1)
        - `salt`: string 8 octet salt **Required for types 1 & 3**
        - `type`: *optional* integer S2K type (default 3)
        - `count`: *optional* integer count code (< 128) used for type 3
          only (default 99)

    :Returns: `S2K` instance

    :note: All keyword parameters can be specified in a dictionary,
        sent as a single parameter (args[0]).
    """
    try:
        kwords = args[0]
    except IndexError:
        pass

    if 'type' in kwords:
        s2ktype = kwords['type']
    else:
        s2ktype = 3
    if 'alg_hash' in kwords:
        alg_hash = kwords['alg_hash']
    else:
        alg_hash = HASH_SHA1

    d = []
    if 0 == s2ktype:
        d.append('\x00')
        d.append(STN.int2str(alg_hash)[0])
    elif 1 == s2ktype:
        d.append('\x01')
        d.append(STN.int2str(alg_hash)[0])
        d.append(kwords['salt'][:8])
    elif 3 == s2ktype:
        d.append('\x03')
        d.append(STN.int2str(alg_hash)[0])
        d.append(kwords['salt'][:8])
        if 'count' in kwords:
            if 0 < kwords['count'] < 128:
                d.append(STN.int2str(kwords['count']))
            else:
                raise PGPValueError, "S2K count value %s out of range." % kwords['count']
        else:
            d.append('\x63') # 99
    return S2K(''.join(d))
コード例 #7
0
def create_OnePassSignatureBody(*args, **kwords):
    """Create a OnePassSignatureBody instance.

    :Parameters:
        - `args`: ordered parameters
        - `kwords`: parameter keywords
    
    :Returns: `OnePassSignatureBody` instance

    Parameter keywords:
        `sigtype`: integer signature type constant
        `alg_hash`: integer hash algorithm constant
        `alg_pubkey`: integer public key algorithm constant
        `keyid`: string 16-character hex signing key ID
        `nest`: integer nested status
        `version`: integer one-pass version
    """
    if 0 < len(args) and isinstance(args[0], dict):
        kwords = args[0]
    sigtype = kwords.get('sigtype')
    alg_hash = kwords.get('alg_hash')
    alg_pubkey = kwords.get('alg_pubkey')
    keyid = kwords.get('keyid')
    nest = kwords.get('nest')
    version = kwords.setdefault('version', 3)

    errmsg = None
    version_d = STN.int2str(version)
    if 1 < len(version_d):
        errmsg = "One-pass version length (%s octs) exceeded 1 octet limit." % len(version_d)
    sigtype_d = STN.int2str(sigtype)
    if 1 < len(sigtype_d):
        errmsg = "One-pass sigtype length (%s octs) exceeded 1 octet limit." % len(type_d)
    alg_hash_d = STN.int2str(alg_hash)
    if 1 < len(alg_hash_d):
        errmsg = "One-pass hash algorithm length (%s octs) exceeded 1 octet limit." % len(alg_hash_d)
    alg_pubkey_d = STN.int2str(alg_pubkey)
    if 1 < len(alg_pubkey_d):
        errmsg = "One-pass public key algorithm length (%s octs) exceeded 1 octet limit." % len(alg_pubkey_d)
    keyid_d = STN.hex2str(keyid)
    if 8 != len(keyid_d):
        errmsg = "One-pass key ID should be a 16 octet (not %s octs) hex string." % len(keyid)
    nest_d = STN.int2str(nest)
    if 1 < len(nest_d):
        errmsg = "One-pass nest length (%s octs) exceeded 1 octet limit." % len(nest_d)
    if errmsg:
        raise PGPValueError(errmsg)
    d = ''.join([version_d, sigtype_d, alg_hash_d, alg_pubkey_d, keyid_d, nest_d])
    return OnePassSignatureBody(d)
コード例 #8
0
ファイル: crypto.py プロジェクト: Ando02/wubiuefi
def sign_DSA(msg, key_tuple, k=None):
    """Create a DSA signature.

    :Parameters:
        - `msg`: string of data signature applies to 
        - `key_tuple`: tuple of DSA integers (y, g, p, q, x)
          (see `DSA tuple`_)
        - `k`: random integer 2 < k < q (automatically generated by
          default)

    :Returns: tuple (integer, integer) DSA signature values (r, s)

    .. _DSA tuple:

    DSA tuple:

        - `y`: integer DSA public key
        - `g`: integer DSA group
        - `p`: integer DSA prime
        - `q`: integer DSA order
        - `x`: integer DSA secret value
    """
    import Crypto.PublicKey.DSA as DSA
    if k is None: # generate our own k value (2 < k < q)
        import Crypto.Util.number as NUM
        import Crypto.Util.randpool as RND
        rnd = RND.RandomPool()
        q = key_tuple[3]
        while 1:
            k = NUM.getRandomNumber(8*len(STN.int2str(q)), rnd.get_bytes)
            if 2 < k < q:
                break
    dsa = DSA.construct(key_tuple) # note change in ordering
    return dsa.sign(msg, k)
コード例 #9
0
 def test01_int2str_str2int(self):
     "strnum: string/integer inversion (int2str/str2int)"
     body = self.key.body
     for i in [
             body.DSA_p.value, body.DSA_q.value, body.DSA_g.value,
             body.DSA_y.value
     ]:
         self.assertEqual(i, str2int(int2str(i)))
コード例 #10
0
ファイル: Signature.py プロジェクト: Ando02/wubiuefi
def __cat_subpkt_block(subpkts):
    subpkt_d = ''.join([x._d for x in subpkts])
    subpkt_d_len = STN.int2str(len(subpkt_d))

    if 2 >= len(subpkt_d_len):
        return STN.prepad(2, subpkt_d_len) + subpkt_d
    else:
        raise PGPValueError, "Subpacket block length (%s) is unacceptable." % len(subpkt_d_len)
コード例 #11
0
ファイル: LiteralData.py プロジェクト: Zaryob/wubi
def create_LiteralDataBody(*args, **kwords):
    """Create a LiteralDataBody instance.

    :Parameters:
        - `args`: parameter list, will accept keyword dictionary as
          args[0]
        - `kwords`: keyword parameters

    :Keywords:
        - `data`: string of literal data
        - `modified`: integer timestamp of file modification
        - `format`: character 'b' or 't' indicating binary or text
        - `filename`: optional filename associated with data

    :Returns: `LiteralDataBody` instance

    Use the filename '_CONSOLE' to signal extra-careful handling of
    output.
    """
    try:
        if isinstance(args[0], dict):
            kwords = args[0]
    except IndexError:
        pass

    data = kwords.get('data')

    if not data:
        data = ''

    modified = kwords.setdefault('modified', 0)
    format = kwords.setdefault('format', 'b')
    filename = kwords.setdefault('filename', 'outfile')

    if format not in ['b', 't']:
        raise PGPValueError, "Literal data format must be 'b' or 't'. Received->(%s)" % str(format)

    fnlen_d = STN.int2str(len(filename))

    if 1 < len(fnlen_d):
        raise PGPValueError, "Filename length (%s) exceeded 1 octet capacity." % len(fnlen_d)

    modified_d = STN.prepad(4, STN.int2str(modified))
    d = ''.join([format, fnlen_d, filename, modified_d, data])

    return LiteralDataBody(d)
コード例 #12
0
ファイル: crypto.py プロジェクト: Ando02/wubiuefi
def encrypt_public_session(keypkt, key, symalg):
    """Create a public-key encrypted session key.

    :Parameters:
        - `keypkt`: either an `OpenPGP.packet.PublicKey.PublicKey` (or
          subclass) instance or encryption passphrase string
        - `key`: string encryptrion algorithm used for `symalg`
        - `symalg`: integer symmetric encryption algorithm constant

    :Returns: `OpenPGP.packet.PublicKeyEncryptedSessionKey.PublicKeyEncryptedSessionKey` instance
    """
    from openpgp.sap.pkt.Packet import create_Packet
    from openpgp.sap.pkt.PublicKeyEncryptedSessionKey import create_PublicKeyEncryptedSessionKeyBody

    pubalg = keypkt.body.alg
    rnd_prefix = []

    i = 0 # fixing the "intended length" business to 127
    while i <= 63 - len(key): # seems proper, but probably inefficient
        rnd_byte = gen_random(1)

        if '\x00' != rnd_byte:
            rnd_prefix.append(rnd_byte)
            i += 1

    chksum = STN.int2str(STN.checksum(key))[:2]

    if pubalg in [ASYM_RSA_EOS, ASYM_RSA_E]:
        key_tup = (keypkt.body.RSA_n.value, keypkt.body.RSA_e.value)

    elif pubalg in [ASYM_ELGAMAL_EOS, ASYM_ELGAMAL_E]:
        key_tup = (keypkt.body.ELGAMAL_p.value, keypkt.body.ELGAMAL_g.value, keypkt.body.ELGAMAL_y.value)

    else:
        raise NotImplementedError("Unsupported public key algorithm->(%s)." % pubalg)

    padded_key = ''.join(['\x02', ''.join(rnd_prefix), '\x00',
                          STN.int2str(symalg)[0], key, chksum])

    cipher_tup = encrypt_public(pubalg, padded_key, key_tup)

    sesbody = create_PublicKeyEncryptedSessionKeyBody(
        keyid=keypkt.body.id, alg=pubalg, mpis=cipher_tup)

    return create_Packet(PKT_PUBKEYSESKEY, sesbody._d)
コード例 #13
0
ファイル: Signature.py プロジェクト: Zaryob/wubi
def __cat_subpkt_block(subpkts):
    subpkt_d = ''.join([x._d for x in subpkts])
    subpkt_d_len = STN.int2str(len(subpkt_d))

    if 2 >= len(subpkt_d_len):
        return STN.prepad(2, subpkt_d_len) + subpkt_d
    else:
        raise PGPValueError, "Subpacket block length (%s) is unacceptable." % len(
            subpkt_d_len)
コード例 #14
0
ファイル: pkt.py プロジェクト: BackupTheBerlios/pgpyp-svn
def _limit_int2str(i, limit):
    "Ensure that int2str output has enough ('limit') bytes."
    s = int2str(i)[:limit]
    len_s = len(s)

    if len_s < limit:
        s = ((limit - len_s) * '\x00') + s

    return s
コード例 #15
0
ファイル: MPI.py プロジェクト: Ando02/wubiuefi
def create_MPI(i):
    """Create an MPI out of an integer.

    :Parameters:
        - `i`: integer

    :Returns: `MPI` instance
    """
    d = []
    i_d = STN.int2str(i)
    i_length = len(i_d)
    bit_count = STN.sigbits(i_d[0]) + (8 * (i_length - 1))
    i_length_str = STN.int2str(bit_count)

    if 2 < len(i_length_str):
        raise ValueError, "int is larger than two octets can specify - int occupies %s octets" % str(i_length)

    elif 1 == len(i_length_str):
        i_length_str = ''.join(['\x00', i_length_str])

    d.append(i_length_str)
    d.append(i_d)

    return MPI(''.join(d))
コード例 #16
0
ファイル: Packet.py プロジェクト: BackupTheBerlios/pgpyp-svn
def create_Tag(pkttype):
    """Create a Tag (packet tag) instance

    :Parameters:
        - `pkttype`: integer packet type constant (see
          `OpenPGP.constant.packets`)

    :Returns: `OpenPGP.packet.Tag` instance

    :note: Only "new" version tags will be created.
    """
    if 0 <= pkttype <= 63:
        tag_d = STN.int2str(192 | pkttype) # 192 forces new version
        return Tag(tag_d)
    else:
        raise PGPFormatError("Tag type must be in the range 0<=t<=63. Received->(%s)." % pkttype)
コード例 #17
0
ファイル: Packet.py プロジェクト: Zaryob/wubi
def create_Tag(pkttype):
    """Create a Tag (packet tag) instance

    :Parameters:
        - `pkttype`: integer packet type constant (see
          `OpenPGP.constant.packets`)

    :Returns: `OpenPGP.packet.Tag` instance

    :note: Only "new" version tags will be created.
    """
    if 0 <= pkttype <= 63:
        tag_d = STN.int2str(192 | pkttype)  # 192 forces new version
        return Tag(tag_d)
    else:
        raise PGPFormatError(
            "Tag type must be in the range 0<=t<=63. Received->(%s)." %
            pkttype)
コード例 #18
0
def create_PublicKeyEncryptedSessionKeyBody(*args, **kwords):
    """
    """
    try:
        kwords = args[0]
    except IndexError:
        pass
    version = '\x03'
    keyid = STN.hex2str(kwords['keyid'])
    algorithm = STN.int2str(kwords['alg'])[0]
    if kwords['alg'] in [ASYM_RSA_EOS, ASYM_RSA_E, ASYM_RSA_S]:
        mpi_d = MPI.create_MPI(kwords['mpis'][0])._d
    elif ASYM_ELGAMAL_E == kwords['alg']:
        a_d = MPI.create_MPI(kwords['mpis'][0])._d
        b_d = MPI.create_MPI(kwords['mpis'][1])._d
        mpi_d = ''.join([a_d, b_d])
    else:
        raise PGPValueError, "Unsupported public key algorithm. Received alg->(%s)" % alg
    _d = ''.join([version, keyid, algorithm, mpi_d])
    return PublicKeyEncryptedSessionKeyBody(_d)
コード例 #19
0
def create_PublicKeyEncryptedSessionKeyBody(*args, **kwords):
    """
    """
    try:
        kwords = args[0]
    except IndexError:
        pass
    version = '\x03'
    keyid = STN.hex2str(kwords['keyid'])
    algorithm = STN.int2str(kwords['alg'])[0]
    if kwords['alg'] in [ASYM_RSA_EOS, ASYM_RSA_E, ASYM_RSA_S]:
        mpi_d = MPI.create_MPI(kwords['mpis'][0])._d
    elif ASYM_ELGAMAL_E == kwords['alg']:
        a_d = MPI.create_MPI(kwords['mpis'][0])._d
        b_d = MPI.create_MPI(kwords['mpis'][1])._d
        mpi_d = ''.join([a_d, b_d])
    else:
        raise PGPValueError, "Unsupported public key algorithm. Received alg->(%s)" % alg
    _d = ''.join([version, keyid, algorithm, mpi_d])
    return PublicKeyEncryptedSessionKeyBody(_d)
コード例 #20
0
ファイル: Signature.py プロジェクト: Ando02/wubiuefi
def create_SignatureSubpacket(type, value):
    """Create a SignatureSubpacket instance.

    :Parameters:
        - `type`: integer signature subpacket type constant
          (see `OpenPGP.constant.signatures`)
        - `value`: variable value depending on `type` (see
          `Subpacket types and values`_)

    :Returns: `SignatureSubpacket` instance

    .. _Subpacket types and values:

    Subpacket types and values:
 
        - ``SIGSUB_SIGNERID``: hex key ID string (16 octets)
        - ``SIGSUB_CREATED``: integer timestamp of signature
          creation(must resolve to 4 or less octets, restricting
          value to less than 4294967296)
        - ``SIGSUB_EXPIRES``, ``SIGSUB_KEYEXPIRES``: integer time past
          creation of signature or key expiration (must resolve to 4
          or less octets, restricting value to less than 4294967296)
        - ``SIGSUB_EXPORTABLE``, `SIGSUB_REVOCABLE``,
          ``SIGSUB_PRIMARYUID``: integer 1 or 0 for True or False
        - ``SIGSUB_TRUST``: tuple(integer level, integer amount)
        - ``SIGSUB_SYMCODE``, ``SIGSUB_HASHALGS``, ``SIGSUB_COMPALGS``,
          ``SIGSUB_KEYSERVPREFS``, ``SIGSUB_KEYFLAGS``,
          ``SIGSUB_FEATURES``: list of integers, see rfc2440 for
          specifics
        - ``SIGSUB_REVOKER``: tuple(integer class, integer algorithm,
          string 40 octet caps hex SHA1 fingerprint hash string
        - ``SIGSUB_NOTATION``: tuple([list of 4 flags], string name,
          string value) see rfc2440 for specifics, list of flags may
          be replaced with None for basic text notation
          [0x80, 0x0, 0x0, 0x0]
        - ``SIGSUB_KEYSERV``, ``SIGSUB_POLICYURL``,
          ``SIGSUB_SIGNERUID``, ``SIGSUB_REGEX``: string see rfc2440
          for specifics
        - ``SIGSUB_REVOCREASON``: tuple (integer code, string reason)
        - ``SIGSUB_SIGTARGET``: Not Implemented
    """
    from Packet import create_NewLength

    # set value_d
    if SIGSUB_SIGNERID == type:
        value_d = STN.hex2str(value)

        if len(value_d) != 8:
            raise SignatureSubpacketValueError("Length of subpacket key id (%s) is not 8 octets." % len(value))

    elif type in [SIGSUB_CREATED, SIGSUB_EXPIRES, SIGSUB_KEYEXPIRES]:
        value_d = STN.int2str(value)

        while len(value_d) < 4:
            value_d = '\x00' + value_d

        if len(value_d) > 4:
            raise SignatureSubpacketValueError("Length of subpacket time (%s) exceeds 4 octet limit." % len(value_d))

    elif type in [SIGSUB_EXPORTABLE, SIGSUB_REVOCABLE, SIGSUB_PRIMARYUID]:

        if value not in [0, 1]:
            raise SignatureSubpacketValueError("Subpacket (# %s) value must be 0 or 1." % (str(subtype)))
        else:
            value_d = STN.int2str(value)

    elif SIGSUB_TRUST == type: # level, amount
        value_d = STN.int2str(value[0]) + STN.int2str(value[1])

    elif type in [SIGSUB_SYMCODE, SIGSUB_HASHCODE, SIGSUB_COMPCODE,
                  SIGSUB_KEYSERVPREFS, SIGSUB_KEYFLAGS, SIGSUB_FEATURES]:
        value_d = ''.join([STN.int2str(x) for x in value])

    elif SIGSUB_REVOKER == type: #
        value_d = STN.int2str(value[0]) + STN.int2str(value[1]) + STN.hex2str(value[2])

    elif SIGSUB_NOTE == type: # [f1, f2, f3, f4], name, value
        # TODO need check for oversized flags
        if value[0]: # allow for basic text notations w/ "not value[0]"
            flag_d = ''.join([STN.int2str(x) for x in value[0]]) # first four flag octs
        else:
            flag_d = '\x80\x00\x00\x00'

        nam, val = value[1], value[2]
        namlen, vallen = STN.int2str(len(nam)), STN.int2str(len(val))

        if len(namlen) == 1:
            namlen = '\x00' + namlen
        elif len(namlen) > 2:
            raise SignatureSubpacketValueError("Length (%s) of subpacket notation 'name' exceeds 2 octet limit." % len(nam))

        if len(vallen) == 1:
            vallen = '\x00' + vallen
        elif len(vallen) > 2:
            raise SignatureSubpacketValueError("Length (%s) of subpacket notation 'value' exceeds 2 octet limit." % len(val))

        value_d = flag_d + namlen + vallen + nam + val

    elif type in [SIGSUB_KEYSERV, SIGSUB_POLICYURL, SIGSUB_SIGNERUID, SIGSUB_REGEX]:
        value_d = value

    elif SIGSUB_REVOCREASON == type: # code, reason
        value_d = STN.int2str(value[0]) + value[1]

    elif SIGSUB_SIGTARGET == type:
        raise NotImplementedError, "SIGTARGET not supported"

    else: # subpacket is an unknown type, so just pack the data in
        value_d = value

    # resolve length string
    len_d = len(value_d) + 1 # + 1 octet type
    slice = create_NewLength(len_d)._d

    # set type string (character)
    type_d = STN.int2str(type)[0]
    subpkt_d = ''.join([slice, type_d, value_d])

    return SignatureSubpacket(subpkt_d)
コード例 #21
0
ファイル: Signature.py プロジェクト: Zaryob/wubi
def create_SignatureSubpacket(type, value):
    """Create a SignatureSubpacket instance.

    :Parameters:
        - `type`: integer signature subpacket type constant
          (see `OpenPGP.constant.signatures`)
        - `value`: variable value depending on `type` (see
          `Subpacket types and values`_)

    :Returns: `SignatureSubpacket` instance

    .. _Subpacket types and values:

    Subpacket types and values:
 
        - ``SIGSUB_SIGNERID``: hex key ID string (16 octets)
        - ``SIGSUB_CREATED``: integer timestamp of signature
          creation(must resolve to 4 or less octets, restricting
          value to less than 4294967296)
        - ``SIGSUB_EXPIRES``, ``SIGSUB_KEYEXPIRES``: integer time past
          creation of signature or key expiration (must resolve to 4
          or less octets, restricting value to less than 4294967296)
        - ``SIGSUB_EXPORTABLE``, `SIGSUB_REVOCABLE``,
          ``SIGSUB_PRIMARYUID``: integer 1 or 0 for True or False
        - ``SIGSUB_TRUST``: tuple(integer level, integer amount)
        - ``SIGSUB_SYMCODE``, ``SIGSUB_HASHALGS``, ``SIGSUB_COMPALGS``,
          ``SIGSUB_KEYSERVPREFS``, ``SIGSUB_KEYFLAGS``,
          ``SIGSUB_FEATURES``: list of integers, see rfc2440 for
          specifics
        - ``SIGSUB_REVOKER``: tuple(integer class, integer algorithm,
          string 40 octet caps hex SHA1 fingerprint hash string
        - ``SIGSUB_NOTATION``: tuple([list of 4 flags], string name,
          string value) see rfc2440 for specifics, list of flags may
          be replaced with None for basic text notation
          [0x80, 0x0, 0x0, 0x0]
        - ``SIGSUB_KEYSERV``, ``SIGSUB_POLICYURL``,
          ``SIGSUB_SIGNERUID``, ``SIGSUB_REGEX``: string see rfc2440
          for specifics
        - ``SIGSUB_REVOCREASON``: tuple (integer code, string reason)
        - ``SIGSUB_SIGTARGET``: Not Implemented
    """
    from Packet import create_NewLength

    # set value_d
    if SIGSUB_SIGNERID == type:
        value_d = STN.hex2str(value)

        if len(value_d) != 8:
            raise SignatureSubpacketValueError(
                "Length of subpacket key id (%s) is not 8 octets." %
                len(value))

    elif type in [SIGSUB_CREATED, SIGSUB_EXPIRES, SIGSUB_KEYEXPIRES]:
        value_d = STN.int2str(value)

        while len(value_d) < 4:
            value_d = '\x00' + value_d

        if len(value_d) > 4:
            raise SignatureSubpacketValueError(
                "Length of subpacket time (%s) exceeds 4 octet limit." %
                len(value_d))

    elif type in [SIGSUB_EXPORTABLE, SIGSUB_REVOCABLE, SIGSUB_PRIMARYUID]:

        if value not in [0, 1]:
            raise SignatureSubpacketValueError(
                "Subpacket (# %s) value must be 0 or 1." % (str(subtype)))
        else:
            value_d = STN.int2str(value)

    elif SIGSUB_TRUST == type:  # level, amount
        value_d = STN.int2str(value[0]) + STN.int2str(value[1])

    elif type in [
            SIGSUB_SYMCODE, SIGSUB_HASHCODE, SIGSUB_COMPCODE,
            SIGSUB_KEYSERVPREFS, SIGSUB_KEYFLAGS, SIGSUB_FEATURES
    ]:
        value_d = ''.join([STN.int2str(x) for x in value])

    elif SIGSUB_REVOKER == type:  #
        value_d = STN.int2str(value[0]) + STN.int2str(value[1]) + STN.hex2str(
            value[2])

    elif SIGSUB_NOTE == type:  # [f1, f2, f3, f4], name, value
        # TODO need check for oversized flags
        if value[0]:  # allow for basic text notations w/ "not value[0]"
            flag_d = ''.join([STN.int2str(x)
                              for x in value[0]])  # first four flag octs
        else:
            flag_d = '\x80\x00\x00\x00'

        nam, val = value[1], value[2]
        namlen, vallen = STN.int2str(len(nam)), STN.int2str(len(val))

        if len(namlen) == 1:
            namlen = '\x00' + namlen
        elif len(namlen) > 2:
            raise SignatureSubpacketValueError(
                "Length (%s) of subpacket notation 'name' exceeds 2 octet limit."
                % len(nam))

        if len(vallen) == 1:
            vallen = '\x00' + vallen
        elif len(vallen) > 2:
            raise SignatureSubpacketValueError(
                "Length (%s) of subpacket notation 'value' exceeds 2 octet limit."
                % len(val))

        value_d = flag_d + namlen + vallen + nam + val

    elif type in [
            SIGSUB_KEYSERV, SIGSUB_POLICYURL, SIGSUB_SIGNERUID, SIGSUB_REGEX
    ]:
        value_d = value

    elif SIGSUB_REVOCREASON == type:  # code, reason
        value_d = STN.int2str(value[0]) + value[1]

    elif SIGSUB_SIGTARGET == type:
        raise NotImplementedError, "SIGTARGET not supported"

    else:  # subpacket is an unknown type, so just pack the data in
        value_d = value

    # resolve length string
    len_d = len(value_d) + 1  # + 1 octet type
    slice = create_NewLength(len_d)._d

    # set type string (character)
    type_d = STN.int2str(type)[0]
    subpkt_d = ''.join([slice, type_d, value_d])

    return SignatureSubpacket(subpkt_d)
コード例 #22
0
ファイル: Signature.py プロジェクト: Zaryob/wubi
def create_SignatureBody(*args, **kwords):
    """Assemble signature information into a SignatureBody instance.

    :Parameters:
        - `args`: parameter list
        - `kwords`: keyword parameter dictionary 
    
    :Keywords:
        - `sigtype`: integer signature type constant (see
          `OpenPGP.constant.signatures`)
        - `alg_pubkey`: integer signature algorithm (see
          `OpenPGP.constant.algorithms`)
        - `alg_hash`: integer signature algorithm (see
          `OpenPGP.constant.algorithms`)
        - `signature`: algorithm-dependent signature MPIs - DSA
          MPI tuple (``DSA_r``, ``DSA_s``), single RSA MPI ``RSA``, or
          ElGamal MPI tuple (``ELGAMAL_a``, ``ELGAMAL_b``) (see
          `DSA signature tuple`_, `RSA signature value`_, and `ElGamal
          signature tuple`_)
        - `hash_frag`: 2 octet string of signed hash fragment
        - `hashed_subpkts`: list of `SignatureSubpacket` instances
          included in the hashed (protected) portion of the signature
        - `unhashed_subpkts`: list of `SignatureSubpacket` instances
          included in the unhashed (unprotected) portion of the signature
        - `created`: integer timestamp of signature creation, **v3 only**
        - `keyid`: string ID of signing key **v3 only**

    :Returns: `SignatureBody` instance

    .. _DSA signature tuple:
    
    DSA signature tuple (``DSA_r``, ``DSA_s``):

        - `DSA_r`: `OpenPGP.packet.MPI` instance
        - `DSA_s`: `OpenPGP.packet.MPI` instance

    .. _RSA signature value:

    RSA signature value ``RSA``:

        - ``RSA``: `OpenPGP.packet.MPI` instance

    .. _ElGamal signature tuple:

    ElGamal signature tuple (``ELGAMAL_a``, ``ELGAMAL_b``):

        - ``ELGAMAL_a``: `OpenPGP.packet.MPI` instance
        - ``ELGAMAL_b``: `OpenPGP.packet.MPI` instance

    :note: This function only assembles the provided information into
        a signature packet, it does not reconcile anything - namely,
        the values of the MPIs with the signed data and hash fragment.
    
    :note: All keyword parameters can be specified in a dictionary,
        sent as a single parameter (args[0]).
    """
    try:
        kwords = args[0]
    except IndexError:
        pass

    version = kwords['version']
    sigtype = kwords['sigtype']
    alg_pubkey = kwords['alg_pubkey']
    alg_hash = kwords['alg_hash']
    signature = kwords['signature']
    hash_frag = kwords['hash_frag']
    hashed_subpkts = kwords.get('hashed_subpkts')  # optional
    unhashed_subpkts = kwords.get('unhashed_subpkts')  # optional

    _d = []
    _d.append(STN.int2str(version)[0])
    ################# version
    if 3 == version:  #################       3
        _d.append('\x05')  # hash length (required)
        _d.append(STN.int2str(sigtype)[0])  # signature type
        _d.append(STN.int2str(kwords['created'])[:4])  # creation timestamp
        _d.append(STN.hex2str(kwords['keyid'])[:8])  # signing key ID
        _d.append(STN.int2str(alg_pubkey)[0])  # public key algorithm
        _d.append(STN.int2str(alg_hash)[0])  # hash algorithm

    elif 4 == version:  #################       4
        _d.append(STN.int2str(sigtype)[0])  # signature type
        _d.append(STN.int2str(alg_pubkey)[0])  # public key algorithm
        _d.append(STN.int2str(alg_hash)[0])  # hash algorithm

        if hashed_subpkts:  # hashed subpackets
            _d.append(__cat_subpkt_block(hashed_subpkts))
        else:
            _d.append('\x00\x00')

        if unhashed_subpkts:  # unhashed subpackets
            _d.append(__cat_subpkt_block(unhashed_subpkts))
        else:
            _d.append('\x00\x00')

    _d.append(hash_frag[:2])  # hash fragment

    if alg_pubkey in [ASYM_RSA_S, ASYM_RSA_EOS]:  # RSA MPI
        _d.append(''.join([x._d for x in signature]))

    elif alg_pubkey in [ASYM_DSA, ASYM_ELGAMAL_EOS]:  # DSA MPIs
        _d.append(''.join([x._d for x in signature]))

    else:
        raise PGPValueError, "Unsupported signature algorithm %s." % algorithm

    return SignatureBody(''.join(_d))
コード例 #23
0
 def test01_int2str_str2int(self):
     "strnum: string/integer inversion (int2str/str2int)"
     body = self.key.body
     for i in [body.DSA_p.value, body.DSA_q.value, body.DSA_g.value, body.DSA_y.value]:
         self.assertEqual(i, str2int(int2str(i)))
コード例 #24
0
ファイル: Signature.py プロジェクト: Ando02/wubiuefi
def create_SignatureBody(*args, **kwords):
    """Assemble signature information into a SignatureBody instance.

    :Parameters:
        - `args`: parameter list
        - `kwords`: keyword parameter dictionary 
    
    :Keywords:
        - `sigtype`: integer signature type constant (see
          `OpenPGP.constant.signatures`)
        - `alg_pubkey`: integer signature algorithm (see
          `OpenPGP.constant.algorithms`)
        - `alg_hash`: integer signature algorithm (see
          `OpenPGP.constant.algorithms`)
        - `signature`: algorithm-dependent signature MPIs - DSA
          MPI tuple (``DSA_r``, ``DSA_s``), single RSA MPI ``RSA``, or
          ElGamal MPI tuple (``ELGAMAL_a``, ``ELGAMAL_b``) (see
          `DSA signature tuple`_, `RSA signature value`_, and `ElGamal
          signature tuple`_)
        - `hash_frag`: 2 octet string of signed hash fragment
        - `hashed_subpkts`: list of `SignatureSubpacket` instances
          included in the hashed (protected) portion of the signature
        - `unhashed_subpkts`: list of `SignatureSubpacket` instances
          included in the unhashed (unprotected) portion of the signature
        - `created`: integer timestamp of signature creation, **v3 only**
        - `keyid`: string ID of signing key **v3 only**

    :Returns: `SignatureBody` instance

    .. _DSA signature tuple:
    
    DSA signature tuple (``DSA_r``, ``DSA_s``):

        - `DSA_r`: `OpenPGP.packet.MPI` instance
        - `DSA_s`: `OpenPGP.packet.MPI` instance

    .. _RSA signature value:

    RSA signature value ``RSA``:

        - ``RSA``: `OpenPGP.packet.MPI` instance

    .. _ElGamal signature tuple:

    ElGamal signature tuple (``ELGAMAL_a``, ``ELGAMAL_b``):

        - ``ELGAMAL_a``: `OpenPGP.packet.MPI` instance
        - ``ELGAMAL_b``: `OpenPGP.packet.MPI` instance

    :note: This function only assembles the provided information into
        a signature packet, it does not reconcile anything - namely,
        the values of the MPIs with the signed data and hash fragment.
    
    :note: All keyword parameters can be specified in a dictionary,
        sent as a single parameter (args[0]).
    """
    try:
        kwords = args[0]
    except IndexError:
        pass

    version = kwords['version']
    sigtype = kwords['sigtype']
    alg_pubkey = kwords['alg_pubkey']
    alg_hash = kwords['alg_hash']
    signature = kwords['signature']
    hash_frag = kwords['hash_frag']
    hashed_subpkts = kwords.get('hashed_subpkts') # optional
    unhashed_subpkts = kwords.get('unhashed_subpkts') # optional

    _d = []
    _d.append(STN.int2str(version)[0])
                                                      ################# version
    if 3 == version:                                  #################       3
        _d.append('\x05')                             # hash length (required)
        _d.append(STN.int2str(sigtype)[0])            # signature type
        _d.append(STN.int2str(kwords['created'])[:4]) # creation timestamp
        _d.append(STN.hex2str(kwords['keyid'])[:8])   # signing key ID
        _d.append(STN.int2str(alg_pubkey)[0])         # public key algorithm
        _d.append(STN.int2str(alg_hash)[0])           # hash algorithm

    elif 4 == version:                                #################       4
        _d.append(STN.int2str(sigtype)[0])            # signature type
        _d.append(STN.int2str(alg_pubkey)[0])         # public key algorithm
        _d.append(STN.int2str(alg_hash)[0])           # hash algorithm

        if hashed_subpkts:                            # hashed subpackets
            _d.append(__cat_subpkt_block(hashed_subpkts))
        else:
            _d.append('\x00\x00')

        if unhashed_subpkts:                          # unhashed subpackets
            _d.append(__cat_subpkt_block(unhashed_subpkts))
        else:
            _d.append('\x00\x00')

    _d.append(hash_frag[:2])                          # hash fragment

    if alg_pubkey in [ASYM_RSA_S, ASYM_RSA_EOS]:      # RSA MPI
        _d.append(''.join([x._d for x in signature]))

    elif alg_pubkey in [ASYM_DSA, ASYM_ELGAMAL_EOS]:  # DSA MPIs
        _d.append(''.join([x._d for x in signature]))

    else:
        raise PGPValueError, "Unsupported signature algorithm %s." % algorithm

    return SignatureBody(''.join(_d))
コード例 #25
-1
ファイル: crypto.py プロジェクト: Ando02/wubiuefi
def sign_ElGamal(msg, key_tuple, k=None):
    """Create an ElGamal signature.

    :Parameters:
        - `msg`: string of data signature applies to 
        - `key_tuple`: tuple ElGamal key integers (p, g, x)
          (see `ElGamal key tuple`_)
        - `k`: integer (must be relatively prime to p-1)

    :Returns: tuple (integer, integer) ElGamal signature values (a, b)
    
    .. _ElGamal key tuple:

    ElGamal key tuple:
            
        - `p`: integer ElGamal prime
        - `g`: integer ElGamal random "g" value
        - `x`: integer ElGamal private key
    """
    import Crypto.PublicKey.ElGamal as ELG
    if k is None: # generate our own prime k value (k relatively prime to p-1)
        import Crypto.Util.number as NUM
        import Crypto.Util.randpool as RND
        rnd = RND.RandomPool()
        q = key_tuple[0] # no restrictions on bit length for k, good enough?
        k = NUM.getPrime(8*len(STN.int2str(q)), rnd.get_bytes)
    elg = ELG.construct((key_tuple[0], key_tuple[1], 0, key_tuple[2]))
    return elg.sign(msg, k)