예제 #1
0
    def sendPacket(self, messageType, payload):
        """
        Sends a packet.  If it's been set up, compress the data, encrypt it,
        and authenticate it before sending.

        @param messageType: The type of the packet; generally one of the
                            MSG_* values.
        @type messageType: C{int}
        @param payload: The payload for the message.
        @type payload: C{str}
        """
        payload = chr(messageType) + payload
        if self.outgoingCompression:
            payload = (self.outgoingCompression.compress(payload)
                       + self.outgoingCompression.flush(2))
        bs = self.currentEncryptions.encBlockSize
        # 4 for the packet length and 1 for the padding length
        totalSize = 5 + len(payload)
        lenPad = bs - (totalSize % bs)
        if lenPad < 4:
            lenPad = lenPad + bs
        packet = (struct.pack('!LB',
                              totalSize + lenPad - 4, lenPad) +
                  payload + randbytes.secureRandom(lenPad))
        encPacket = (
            self.currentEncryptions.encrypt(packet) +
            self.currentEncryptions.makeMAC(
                self.outgoingPacketSequence, packet))
        self.transport.write(encPacket)
        self.outgoingPacketSequence += 1
예제 #2
0
    def sendPacket(self, messageType, payload):
        """
        Override because OpenSSH pads with 0 on KEXINIT
        """
        if self._keyExchangeState != self._KEY_EXCHANGE_NONE:
            if not self._allowedKeyExchangeMessageType(messageType):
                self._blockedByKeyExchange.append((messageType, payload))
                return

        payload = chr(messageType) + payload
        if self.outgoingCompression:
            payload = (self.outgoingCompression.compress(payload)
                       + self.outgoingCompression.flush(2))
        bs = self.currentEncryptions.encBlockSize
        # 4 for the packet length and 1 for the padding length
        totalSize = 5 + len(payload)
        lenPad = bs - (totalSize % bs)
        if lenPad < 4:
            lenPad = lenPad + bs
        if messageType == transport.MSG_KEXINIT:
            padding = b'\0' * lenPad
        else:
            padding = randbytes.secureRandom(lenPad)

        packet = (struct.pack(b'!LB',
                              totalSize + lenPad - 4, lenPad) +
                  payload + padding)
        encPacket = (
            self.currentEncryptions.encrypt(packet) +
            self.currentEncryptions.makeMAC(
                self.outgoingPacketSequence, packet))
        self.transport.write(encPacket)
        self.outgoingPacketSequence += 1
예제 #3
0
파일: component.py 프로젝트: thepaul/wokkel
    def streamStarted(self, rootElement):
        """
        Called by the stream when it has started.

        This examines the default namespace of the incoming stream and whether
        there is a requested hostname for the component. Then it generates a
        stream identifier, sends a response header and adds an observer for
        the first incoming element, triggering L{onElement}.
        """

        xmlstream.ListenAuthenticator.streamStarted(self, rootElement)

        # Compatibility fix for pre-8.2 implementations of ListenAuthenticator
        if not self.xmlstream.sid:
            from twisted.python import randbytes
            self.xmlstream.sid = randbytes.secureRandom(8).encode('hex')

        if rootElement.defaultUri != self.namespace:
            exc = error.StreamError('invalid-namespace')
            self.xmlstream.sendStreamError(exc)
            return

        # self.xmlstream.thisEntity is set to the address the component
        # wants to assume.
        if not self.xmlstream.thisEntity:
            exc = error.StreamError('improper-addressing')
            self.xmlstream.sendStreamError(exc)
            return

        self.xmlstream.sendHeader()
        self.xmlstream.addOnetimeObserver('/*', self.onElement)
예제 #4
0
파일: ampauth.py 프로젝트: bne/squeal
 def passwordLogin(self, username):
     """
     Generate a new challenge for the given username.
     """
     self.challenge = secureRandom(16)
     self.username = username
     return {'challenge': self.challenge}
예제 #5
0
    def perspective_auth_challenge(self):
        """
        Remote method for requesting to begin the challenge/response
        Authorization handshake.  Start by creating a random, signed challenge
        string that is encrypted using the clients public key.  Only the client
        with the correct key can decrypt it and send it back

        If the Avatar does not have the public key for the client attempting to
        connect it will return -1 indicating as such.  This allows the client
        to trigger the key exchange (pairing) before retrying.
        """
        if not self.client_key:
            return -1

        challenge = secureRandom(self.key_size/16)

        # encode using master's key, only the matching private
        # key will be able to decode this message
        encrypted = self.client_key.encrypt(challenge, None)[0]

        # now encode and hash the challenge string so it is not stored 
        # plaintext.  It will be received in this same form so it will be 
        # easier to compare
        challenge = self.server_key.encrypt(challenge, None)
        challenge = hashlib.sha512(challenge[0]).hexdigest()

        self.challenge = challenge
        self.challenged = True

        return encrypted
예제 #6
0
파일: server.py 프로젝트: thepaul/wokkel
    def streamStarted(self, rootElement):
        xmlstream.ListenAuthenticator.streamStarted(self, rootElement)

        # Compatibility fix for pre-8.2 implementations of ListenAuthenticator
        if not self.xmlstream.sid:
            self.xmlstream.sid = randbytes.secureRandom(8).encode('hex')

        if self.xmlstream.thisEntity:
            targetDomain = self.xmlstream.thisEntity.host
        else:
            targetDomain = self.service.defaultDomain

        def prepareStream(domain):
            self.xmlstream.namespace = self.namespace
            self.xmlstream.prefixes = {xmlstream.NS_STREAMS: 'stream',
                                       NS_DIALBACK: 'db'}
            if domain:
                self.xmlstream.thisEntity = jid.internJID(domain)

        try:
            if xmlstream.NS_STREAMS != rootElement.uri or \
               self.namespace != self.xmlstream.namespace or \
               ('db', NS_DIALBACK) not in rootElement.localPrefixes.iteritems():
                raise error.StreamError('invalid-namespace')

            if targetDomain and targetDomain not in self.service.domains:
                raise error.StreamError('host-unknown')
        except error.StreamError, exc:
            prepareStream(self.service.defaultDomain)
            self.xmlstream.sendStreamError(exc)
            return
예제 #7
0
    def _toString_OPENSSH(self, extra):
        """
        Return a public or private OpenSSH string.  See
        _fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the
        string formats.  If extra is present, it represents a comment for a
        public key, or a passphrase for a private key.

        @param extra: Comment for a public key or passphrase for a
            private key
        @type extra: L{bytes}

        @rtype: L{bytes}
        """
        data = self.data()
        if self.isPublic():
            b64Data = base64.encodestring(self.blob()).replace(b'\n', b'')
            if not extra:
                extra = b''
            return (self.sshType() + b' ' + b64Data + b' ' + extra).strip()
        else:
            lines = [b''.join((b'-----BEGIN ', self.type().encode('ascii'),
                               b' PRIVATE KEY-----'))]
            if self.type() == 'RSA':
                p, q = data['p'], data['q']
                objData = (0, data['n'], data['e'], data['d'], q, p,
                           data['d'] % (q - 1), data['d'] % (p - 1),
                           data['u'])
            else:
                objData = (0, data['p'], data['q'], data['g'], data['y'],
                           data['x'])
            asn1Sequence = univ.Sequence()
            for index, value in izip(itertools.count(), objData):
                asn1Sequence.setComponentByPosition(index, univ.Integer(value))
            asn1Data = berEncoder.encode(asn1Sequence)
            if extra:
                iv = randbytes.secureRandom(8)
                hexiv = ''.join(['%02X' % (ord(x),) for x in iterbytes(iv)])
                hexiv = hexiv.encode('ascii')
                lines.append(b'Proc-Type: 4,ENCRYPTED')
                lines.append(b'DEK-Info: DES-EDE3-CBC,' + hexiv + b'\n')
                ba = md5(extra + iv).digest()
                bb = md5(ba + extra + iv).digest()
                encKey = (ba + bb)[:24]
                padLen = 8 - (len(asn1Data) % 8)
                asn1Data += (chr(padLen) * padLen).encode('ascii')

                encryptor = Cipher(
                    algorithms.TripleDES(encKey),
                    modes.CBC(iv),
                    backend=default_backend()
                ).encryptor()

                asn1Data = encryptor.update(asn1Data) + encryptor.finalize()

            b64Data = base64.encodestring(asn1Data).replace(b'\n', b'')
            lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)]
            lines.append(b''.join((b'-----END ', self.type().encode('ascii'),
                                   b' PRIVATE KEY-----')))
            return b'\n'.join(lines)
예제 #8
0
파일: common.py 프로젝트: Almad/twisted
 def get_bytes(self, numBytes):
     """
     Get a number of random bytes.
     """
     warnings.warn("entropy.get_bytes is deprecated, please use "
                   "twisted.python.randbytes.secureRandom instead.",
         category=DeprecationWarning, stacklevel=2)
     return randbytes.secureRandom(numBytes)
예제 #9
0
    def _generateNonce(self):
        """
        Create a random value suitable for use as the nonce parameter of a
        WWW-Authenticate challenge.

        @rtype: L{bytes}
        """
        return hexlify(secureRandom(12))
예제 #10
0
파일: credentials.py 프로젝트: 0004c/VTK
    def _generateNonce(self):
        """
        Create a random value suitable for use as the nonce parameter of a
        WWW-Authenticate challenge.

        @rtype: C{str}
        """
        return secureRandom(12).encode('hex')
예제 #11
0
 def test_bad_response(self):
     """
     Test the response function when given an incorrect response
     """
     avatar = RSAAvatar(self.priv_key, None, self.pub_key, key_size=KEY_SIZE)
     challenge = avatar.perspective_auth_challenge()
     #create response that can't be string because its longer than the hash
     response = secureRandom(600)
     result = avatar.perspective_auth_response(response)
     self.assertEqual(result, -1, 'auth_response should return error (-1) when given bad response')
     self.assertFalse(avatar.authenticated, 'avatar.authenticated flag should be False if auth_response fails')
예제 #12
0
 def generateOneTimePad(self, userStore):
     """
     Generate a pad which can be used to authenticate via AMP.  This pad
     will expire in L{ONE_TIME_PAD_DURATION} seconds.
     """
     pad = secureRandom(16).encode('hex')
     self._oneTimePads[pad] = userStore.idInParent
     def expirePad():
         self._oneTimePads.pop(pad, None)
     self.callLater(self.ONE_TIME_PAD_DURATION, expirePad)
     return pad
예제 #13
0
파일: ampauth.py 프로젝트: bne/squeal
    def determineFrom(cls, challenge, password):
        """
        Create a nonce and use it, along with the given challenge and password,
        to generate the parameters for a response.

        @return: A C{dict} suitable to be used as the keyword arguments when
            calling this command.
        """
        nonce = secureRandom(16)
        response = _calcResponse(challenge, nonce, password)
        return dict(cnonce=nonce, response=response)
예제 #14
0
    def _makeProxy(self):
        while True:
            token = base64.b64encode(secureRandom(9, False), '-_')

            if token not in proxies:
                proxies[token] = { 'ct': None, 'ident': None, 'request': None, 'creds': None }
                syslog.syslog(syslog.LOG_INFO, "Created proxy " + token)
                break

        reactor.callLater(PROXY_LIFETIME, self._deleteProxy, token)
        return token
예제 #15
0
    def __init__(self, config, router):
        self.config = config
        self.defaultDomain = config['network']
        self.domains = set()
        self.domains.add(self.defaultDomain)
        self.secret = randbytes.secureRandom(16).encode('hex')
        self.router = router

        self._outgoingStreams = {}
        self._outgoingQueues = {}
        self._outgoingConnecting = set()
        self.serial = 0
예제 #16
0
    def verify_keys(self, pub_key, priv_key):
        """
        helper function for verifying two keys work together
        """
        bytes = KEY_SIZE/16
        bytes = secureRandom(bytes)

        enc = pub_key.encrypt(bytes, None)
        dec = priv_key.decrypt(enc)
        self.assertEqual(bytes, dec, 'Publickey encrypted bytes could not be decrypted by Privatekey')

        enc = priv_key.encrypt(bytes, None)
        dec = priv_key.decrypt(enc)
        self.assertEqual(bytes, dec, 'Privatekey encrypted bytes could not be decrypted by Privatekey')
예제 #17
0
파일: gelf.py 프로젝트: Kelfast/txGraylog
    def _get_chunks(self, compressed):
        """Split the compressed log paramaters into chunks
        """
        num_chunks = (len(compressed) / self.chunk_size) + 1

        if self.gelf_format == GELF_LEGACY:
            pieces = struct.pack('>H', num_chunks)
            chunk_id = uuid.uuid1().bytes + randbytes.secureRandom(16)

            for i in xrange(num_chunks):
                chunk = ''.join([
                    '\x1e\x0f',
                    chunk_id,
                    struct.pack('>H', i),
                    pieces,
                    compressed[
                        i * self.chunk_size:
                        i * self.chunk_size + self.chunk_size]
                    ]
                )
                yield chunk
        else:
            pieces = struct.pack('B', num_chunks)
            chunk_id = randbytes.secureRandom(8)

            for i in xrange(num_chunks):
                chunk = ''.join([
                    '\x1e\x0f',
                    chunk_id,
                    struct.pack('B', i),
                    pieces,
                    compressed[
                        i * self.chunk_size:
                        i * self.chunk_size + self.chunk_size]
                    ]
                )
                yield chunk
예제 #18
0
    def _toString_OPENSSH(self, extra):
        """
        Return a public or private OpenSSH string.  See
        _fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the
        string formats.  If extra is present, it represents a comment for a
        public key, or a passphrase for a private key.

        @param extra: Comment for a public key or passphrase for a
            private key
        @type extra: C{str}

        @rtype: C{str}
        """
        data = self.data()
        if self.isPublic():
            b64Data = base64.encodestring(self.blob()).replace('\n', '')
            if not extra:
                extra = ''
            return ('%s %s %s' % (self.sshType(), b64Data, extra)).strip()
        else:
            lines = ['-----BEGIN %s PRIVATE KEY-----' % self.type()]
            if self.type() == 'RSA':
                p, q = data['p'], data['q']
                objData = (0, data['n'], data['e'], data['d'], q, p,
                           data['d'] % (q - 1), data['d'] % (p - 1),
                           data['u'])
            else:
                objData = (0, data['p'], data['q'], data['g'], data['y'],
                           data['x'])
            asn1Sequence = univ.Sequence()
            for index, value in itertools.izip(itertools.count(), objData):
                asn1Sequence.setComponentByPosition(index, univ.Integer(value))
            asn1Data = berEncoder.encode(asn1Sequence)
            if extra:
                iv = randbytes.secureRandom(8)
                hexiv = ''.join(['%02X' % ord(x) for x in iv])
                lines.append('Proc-Type: 4,ENCRYPTED')
                lines.append('DEK-Info: DES-EDE3-CBC,%s\n' % hexiv)
                ba = md5(extra + iv).digest()
                bb = md5(ba + extra + iv).digest()
                encKey = (ba + bb)[:24]
                padLen = 8 - (len(asn1Data) % 8)
                asn1Data += (chr(padLen) * padLen)
                asn1Data = DES3.new(encKey, DES3.MODE_CBC,
                                    iv).encrypt(asn1Data)
            b64Data = base64.encodestring(asn1Data).replace('\n', '')
            lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)]
            lines.append('-----END %s PRIVATE KEY-----' % self.type())
            return '\n'.join(lines)
예제 #19
0
    def addHostKey(self, hostname, key):
        """
        Add a new L{HashedEntry} to the key database.

        Note that you still need to call L{KnownHostsFile.save} if you wish
        these changes to be persisted.

        @return: the L{HashedEntry} that was added.
        """
        salt = secureRandom(20)
        keyType = "ssh-" + key.type().lower()
        entry = HashedEntry(salt, _hmacedString(salt, hostname),
                            keyType, key, None)
        self._entries.append(entry)
        return entry
예제 #20
0
 def sendKexInit(self):
     self.ourKexInitPayload = (chr(MSG_KEXINIT) +
            randbytes.secureRandom(16) +
            NS(','.join(self.supportedKeyExchanges)) +
            NS(','.join(self.supportedPublicKeys)) +
            NS(','.join(self.supportedCiphers)) +
            NS(','.join(self.supportedCiphers)) +
            NS(','.join(self.supportedMACs)) +
            NS(','.join(self.supportedMACs)) +
            NS(','.join(self.supportedCompressions)) +
            NS(','.join(self.supportedCompressions)) +
            NS(','.join(self.supportedLanguages)) +
            NS(','.join(self.supportedLanguages)) +
            '\000' + '\000\000\000\000')
     self.sendPacket(MSG_KEXINIT, self.ourKexInitPayload[1:])
예제 #21
0
    def authenticate(self, user):
        """
        Starts the authentication process by generating a challenge string
        """
        # create a random challenge.  The plaintext string must be hashed
        # so that it is safe to be sent over the AMF service.
        challenge = hashlib.sha512(secureRandom(self.key_size/16)).hexdigest()

        # now encode and hash the challenge string so it is not stored 
        # plaintext.  It will be received in this same form so it will be 
        # easier to compare
        challenge_enc = self.priv_key_encrypt(challenge, None)
        challenge_hash = hashlib.sha512(challenge_enc[0]).hexdigest()

        self.sessions[user]['challenge'] = challenge_hash
        return challenge
예제 #22
0
파일: xmlstream.py 프로젝트: Almad/twisted
    def streamStarted(self, rootElement):
        """
        Called by the XmlStream when the stream has started.

        This extends L{Authenticator.streamStarted} to extract further
        information from the stream headers from L{rootElement}.
        """
        Authenticator.streamStarted(self, rootElement)

        self.xmlstream.namespace = rootElement.defaultUri

        if rootElement.hasAttribute("to"):
            self.xmlstream.thisEntity = jid.internJID(rootElement["to"])

        self.xmlstream.prefixes = {}
        for prefix, uri in rootElement.localPrefixes.iteritems():
            self.xmlstream.prefixes[uri] = prefix

        self.xmlstream.sid = randbytes.secureRandom(8).encode('hex')
예제 #23
0
    def sign(self, data):
        """
        Returns a signature with this Key.

        @type data: C{str}
        @rtype: C{str}
        """
        if self.type() == 'RSA':
            digest = pkcs1Digest(data, self.keyObject.size()/8)
            signature = self.keyObject.sign(digest, '')[0]
            ret = common.NS(Util.number.long_to_bytes(signature))
        elif self.type() == 'DSA':
            digest = sha.new(data).digest()
            randomBytes = randbytes.secureRandom(19)
            sig = self.keyObject.sign(digest, randomBytes)
            # SSH insists that the DSS signature blob be two 160-bit integers
            # concatenated together. The sig[0], [1] numbers from obj.sign
            # are just numbers, and could be any length from 0 to 160 bits.
            # Make sure they are padded out to 160 bits (20 bytes each)
            ret = common.NS(Util.number.long_to_bytes(sig[0], 20) +
                             Util.number.long_to_bytes(sig[1], 20))
        return common.NS(self.sshType()) + ret
예제 #24
0
파일: server.py 프로젝트: thepaul/wokkel
    def __init__(self, router, domain=None, secret=None):
        self.router = router

        self.defaultDomain = domain
        self.domains = set()
        if self.defaultDomain:
            self.domains.add(self.defaultDomain)

        if secret is not None:
            self.secret = secret
        else:
            self.secret = randbytes.secureRandom(16).encode('hex')

        self._outgoingStreams = {}
        self._outgoingQueues = {}
        self._outgoingConnecting = set()
        self.serial = 0

        pipe = XmlPipe()
        self.xmlstream = pipe.source
        self.router.addRoute(None, pipe.sink)
        self.xmlstream.addObserver('/*', self.send)
예제 #25
0
    def hash_host(hostname, salt=None):
        """
        Return a "hashed" form of the hostname, as used by openssh when storing
        hashed hostnames in the known_hosts file.

        @param hostname: the hostname to hash
        @type hostname: str
        @param salt: optional salt to use when hashing (must be 20 bytes long)
        @type salt: str
        @return: the hashed hostname
        @rtype: str
        """
        if salt is None:
            salt = secureRandom(SHA.digest_size)
        else:
            if salt.startswith('|1|'):
                salt = salt.split('|')[2]
            salt = base64.decodestring(salt)
        assert len(salt) == SHA.digest_size
        hmac = HMAC.HMAC(salt, hostname, SHA).digest()
        hostkey = '|1|%s|%s' % (base64.encodestring(salt), base64.encodestring(hmac))
        return hostkey.replace('\n', '')
예제 #26
0
    def sign(self, data):
        """
        Returns a signature with this Key.

        @type data: C{str}
        @rtype: C{str}
        """
        if self.type() == 'RSA':
            digest = pkcs1Digest(data, self.keyObject.size() / 8)
            signature = self.keyObject.sign(digest, '')[0]
            ret = common.NS(Util.number.long_to_bytes(signature))
        elif self.type() == 'DSA':
            digest = sha1(data).digest()
            randomBytes = randbytes.secureRandom(19)
            sig = self.keyObject.sign(digest, randomBytes)
            # SSH insists that the DSS signature blob be two 160-bit integers
            # concatenated together. The sig[0], [1] numbers from obj.sign
            # are just numbers, and could be any length from 0 to 160 bits.
            # Make sure they are padded out to 160 bits (20 bytes each)
            ret = common.NS(
                Util.number.long_to_bytes(sig[0], 20) +
                Util.number.long_to_bytes(sig[1], 20))
        return common.NS(self.sshType()) + ret
예제 #27
0
    def addHostKey(self, hostname, key):
        """
        Add a new L{HashedEntry} to the key database.

        Note that you still need to call L{KnownHostsFile.save} if you wish
        these changes to be persisted.

        @param hostname: A hostname or IP address literal to associate with the
            new entry.
        @type hostname: L{bytes}

        @param key: The public key to associate with the new entry.
        @type key: L{Key}

        @return: The L{HashedEntry} that was added.
        @rtype: L{HashedEntry}
        """
        salt = secureRandom(20)
        keyType = "ssh-" + key.type().lower()
        entry = HashedEntry(salt, _hmacedString(salt, hostname),
                            keyType, key, None)
        self._added.append(entry)
        return entry
예제 #28
0
    def addHostKey(self, hostname, key):
        """
        Add a new L{HashedEntry} to the key database.

        Note that you still need to call L{KnownHostsFile.save} if you wish
        these changes to be persisted.

        @param hostname: A hostname or IP address literal to associate with the
            new entry.
        @type hostname: L{bytes}

        @param key: The public key to associate with the new entry.
        @type key: L{Key}

        @return: The L{HashedEntry} that was added.
        @rtype: L{HashedEntry}
        """
        salt = secureRandom(20)
        keyType = key.sshType()
        entry = HashedEntry(salt, _hmacedString(salt, hostname),
                            keyType, key, None)
        self._added.append(entry)
        return entry
예제 #29
0
    def call(self,chain):
        # if we already have a session don't recreate it.
        if  "session_secret" in chain:
            return
        # we need an UID before signing in and we need to have been successful atleast once
        if chain.uid is None or not chain._success:
            return

        # twisted.python.randbytes is basically just an alias for os.urandom 
        # it handles fallbacks etc and throws an exception if we don't have a
        # secure random source
        rand = randbytes.secureRandom(16)  
        
        session_secret = rand.encode("hex") # should probably use something more efficent than hex here...
        
        chain['set_session_secret'] = session_secret
        yield self.datasource.set("session:"+session_secret,chain.uid)


        # if an IP address has been specified in the chain
        # set it in the data store

        if "ipaddr" in chain:
            self.datasource.set("session-ip:"+session_secret,chain['ipaddr'])
예제 #30
0
    def render_GET(self, request):
        token = secureRandom(16).encode("hex")
        cache["auth:%s" % token] = request.user.username

        return json.dumps({"rel": "token_auth", "token": token})
예제 #31
0
 def __init__(self, algorithm, authenticationRealm):
     self.algorithm = algorithm
     self.authenticationRealm = authenticationRealm
     self.privateKey = secureRandom(12)
예제 #32
0
 def __init__(self, algorithm, authenticationRealm):
     self.algorithm = algorithm
     self.authenticationRealm = authenticationRealm
     self.privateKey = secureRandom(12)
예제 #33
0
    def _toString_OPENSSH(self, extra):
        """
        Return a public or private OpenSSH string.  See
        _fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the
        string formats.  If extra is present, it represents a comment for a
        public key, or a passphrase for a private key.

        @param extra: Comment for a public key or passphrase for a
            private key
        @type extra: L{bytes}

        @rtype: L{bytes}
        """
        data = self.data()
        if self.isPublic():
            if self.type() == 'EC':
                if not extra:
                    extra = b''
                return (self._keyObject.public_bytes(
                    serialization.Encoding.OpenSSH,
                    serialization.PublicFormat.OpenSSH
                    ) + b' ' + extra).strip()

            b64Data = encodebytes(self.blob()).replace(b'\n', b'')
            if not extra:
                extra = b''
            return (self.sshType() + b' ' + b64Data + b' ' + extra).strip()
        else:

            if self.type() == 'EC':
                # EC keys has complex ASN.1 structure hence we do this this way.
                if not extra:
                    # unencrypted private key
                    encryptor = serialization.NoEncryption()
                else:
                    encryptor = serialization.BestAvailableEncryption(extra)

                return self._keyObject.private_bytes(
                    serialization.Encoding.PEM,
                    serialization.PrivateFormat.TraditionalOpenSSL,
                    encryptor)

            lines = [b''.join((b'-----BEGIN ', self.type().encode('ascii'),
                               b' PRIVATE KEY-----'))]
            if self.type() == 'RSA':
                p, q = data['p'], data['q']
                objData = (0, data['n'], data['e'], data['d'], q, p,
                           data['d'] % (q - 1), data['d'] % (p - 1),
                           data['u'])
            else:
                objData = (0, data['p'], data['q'], data['g'], data['y'],
                           data['x'])
            asn1Sequence = univ.Sequence()
            for index, value in izip(itertools.count(), objData):
                asn1Sequence.setComponentByPosition(index, univ.Integer(value))
            asn1Data = berEncoder.encode(asn1Sequence)
            if extra:
                iv = randbytes.secureRandom(8)
                hexiv = ''.join(['%02X' % (ord(x),) for x in iterbytes(iv)])
                hexiv = hexiv.encode('ascii')
                lines.append(b'Proc-Type: 4,ENCRYPTED')
                lines.append(b'DEK-Info: DES-EDE3-CBC,' + hexiv + b'\n')
                ba = md5(extra + iv).digest()
                bb = md5(ba + extra + iv).digest()
                encKey = (ba + bb)[:24]
                padLen = 8 - (len(asn1Data) % 8)
                asn1Data += (chr(padLen) * padLen).encode('ascii')

                encryptor = Cipher(
                    algorithms.TripleDES(encKey),
                    modes.CBC(iv),
                    backend=default_backend()
                ).encryptor()

                asn1Data = encryptor.update(asn1Data) + encryptor.finalize()

            b64Data = encodebytes(asn1Data).replace(b'\n', b'')
            lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)]
            lines.append(b''.join((b'-----END ', self.type().encode('ascii'),
                                   b' PRIVATE KEY-----')))
            return b'\n'.join(lines)
예제 #34
0
파일: digest.py 프로젝트: DxCx/twimp
def _gen_cnonce():
    return secureRandom(4).encode('hex')
예제 #35
0
def randomSource():
    """
    Wrapper around L{randbytes.secureRandom} to return 2 random chars.
    """
    return struct.unpack('H', randbytes.secureRandom(2, fallback=True))[0]
예제 #36
0
파일: dns.py 프로젝트: jobajuba/Tsunami
def randomSource():
    """
    Wrapper around L{randbytes.secureRandom} to return 2 random chars.
    """
    return struct.unpack('H', randbytes.secureRandom(2, fallback=True))[0]