server side of basic RDP security layer
This commit is contained in:
@@ -310,7 +310,7 @@ class ServerCertificate(CompositeType):
|
||||
@summary: Server certificate structure
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240521.aspx
|
||||
"""
|
||||
def __init__(self, readLen = None, conditional = lambda:True):
|
||||
def __init__(self, certData = None, readLen = None, conditional = lambda:True):
|
||||
CompositeType.__init__(self, readLen = readLen, conditional = conditional)
|
||||
self.dwVersion = UInt32Le()
|
||||
|
||||
@@ -322,7 +322,12 @@ class ServerCertificate(CompositeType):
|
||||
if self.dwVersion.value & 0x7fffffff == c._TYPE_:
|
||||
return c()
|
||||
raise InvalidExpectedDataException("unknown certificate type : %s "%hex(self.dwVersion.value))
|
||||
|
||||
|
||||
if certData is None:
|
||||
certData = FactoryType(CertificateFactory)
|
||||
elif not "_TYPE_" in certData.__class__.__dict__:
|
||||
raise InvalidExpectedDataException("Try to send an invalid Certificate")
|
||||
|
||||
self.certData = FactoryType(CertificateFactory)
|
||||
|
||||
def bin2bn(b):
|
||||
@@ -399,8 +404,8 @@ class RSAPublicKey(CompositeType):
|
||||
CompositeType.__init__(self, readLen = readLen)
|
||||
self.magic = UInt32Le(0x31415352, constant = True)
|
||||
self.keylen = UInt32Le(lambda:sizeof(self.modulus))
|
||||
self.bitlen = UInt32Le()
|
||||
self.datalen = UInt32Le()
|
||||
self.bitlen = UInt32Le(lambda:((self.keylen.value - 8) * 8))
|
||||
self.datalen = UInt32Le(lambda:((self.bitlen.value / 8) - 1))
|
||||
self.pubExp = UInt32Le()
|
||||
self.modulus = String(readLen = UInt16Le(lambda:(self.keylen.value - 8)))
|
||||
self.padding = String(readLen = UInt8(8))
|
||||
|
||||
@@ -31,6 +31,7 @@ from rdpy.protocol.rdp.ber import writeLength
|
||||
import rdpy.core.log as log
|
||||
|
||||
import ber, gcc, per
|
||||
import rsa
|
||||
|
||||
class Message(object):
|
||||
"""
|
||||
@@ -487,8 +488,14 @@ class Server(MCSLayer):
|
||||
"""
|
||||
#basic rdp security layer
|
||||
if self._transport._selectedProtocol == 0:
|
||||
certificate = gcc.ProprietaryServerCertificate()
|
||||
certificate.PublicKeyBlob.modulus.value = hex(self._presentation._rsaPublicKey.n)[2:-1].decode('hex')[::-1]
|
||||
certificate.PublicKeyBlob.pubExp.value = self._presentation._rsaPublicKey.e
|
||||
|
||||
self._serverSettings.SC_SECURITY.encryptionMethod.value = gcc.EncryptionMethod.ENCRYPTION_FLAG_128BIT
|
||||
self._serverSettings.SC_SECURITY.encryptionLevel = gcc.EncryptionLevel.ENCRYPTION_LEVEL_HIGH
|
||||
self._serverSettings.SC_SECURITY.encryptionLevel.value = gcc.EncryptionLevel.ENCRYPTION_LEVEL_HIGH
|
||||
self._serverSettings.SC_SECURITY.serverRandom.value = rsa.randnum.read_random_bits(256)
|
||||
self._serverSettings.SC_SECURITY.serverCertificate.certData = certificate
|
||||
|
||||
self._serverSettings.SC_CORE.clientRequestedProtocol.value = self._transport._requestedProtocol
|
||||
self.setNextState(self.recvConnectInitial)
|
||||
|
||||
@@ -324,11 +324,10 @@ class RDPServerController(pdu.layer.PDUServerListener):
|
||||
"""
|
||||
@summary: Controller use in server side mode
|
||||
"""
|
||||
def __init__(self, colorDepth, privateKeyFileName = None, certificateFileName = None, rsaKeys = None):
|
||||
def __init__(self, colorDepth, privateKeyFileName = None, certificateFileName = None):
|
||||
"""
|
||||
@param privateKeyFileName: file contain server private key
|
||||
@param certficiateFileName: file that contain public key
|
||||
@param rsaKeys: {Tuple(rsa.PublicKey, rsa.PrivateKey)} rsa crypto
|
||||
@param colorDepth: 15, 16, 24
|
||||
"""
|
||||
self._isReady = False
|
||||
@@ -337,7 +336,7 @@ class RDPServerController(pdu.layer.PDUServerListener):
|
||||
#build RDP protocol stack
|
||||
self._pduLayer = pdu.layer.Server(self)
|
||||
#secure layer
|
||||
self._secLayer = sec.Server(self._pduLayer, rsaKeys)
|
||||
self._secLayer = sec.Server(self._pduLayer)
|
||||
#multi channel service
|
||||
self._mcsLayer = mcs.Server(self._secLayer)
|
||||
#transport pdu layer
|
||||
|
||||
@@ -586,15 +586,13 @@ class Server(SecLayer):
|
||||
"""
|
||||
@summary: Client side of security layer
|
||||
"""
|
||||
def __init__(self, presentation, rsaKeys = None):
|
||||
def __init__(self, presentation):
|
||||
"""
|
||||
@param rsaKeys: {Tuple(rsa.PublicKey, rsa.PrivateKey)} rsa crypto
|
||||
@param presentation: {Layer}
|
||||
"""
|
||||
SecLayer.__init__(self, presentation)
|
||||
self._rsaPublicKey, self._rsaPrivateKey = None, None
|
||||
if not rsaKeys is None:
|
||||
self._rsaPublicKey, self._rsaPrivateKey = rsaKeys
|
||||
|
||||
self._rsaPublicKey, self._rsaPrivateKey = rsa.newkeys(512)
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@summary: init automata to wait info packet
|
||||
@@ -612,6 +610,18 @@ class Server(SecLayer):
|
||||
"""
|
||||
message = ClientSecurityExchangePDU()
|
||||
s.readType(message)
|
||||
clientRandom = rsa.decrypt(message.encryptedClientRandom.value, self._rsaPrivateKey)
|
||||
|
||||
self._macKey, self._initialDecrytKey, self._initialEncryptKey = generateKeys( clientRandom,
|
||||
self.getGCCServerSettings().SC_SECURITY.serverRandom.value,
|
||||
self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
|
||||
#initialize keys
|
||||
self._currentDecrytKey = self._initialDecrytKey
|
||||
self._currentEncryptKey = self._initialEncryptKey
|
||||
self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey)
|
||||
self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey)
|
||||
|
||||
self.setNextState(self.recvInfoPkt)
|
||||
|
||||
|
||||
def recvInfoPkt(self, s):
|
||||
|
||||
@@ -256,7 +256,7 @@ class Server(X224Layer):
|
||||
|
||||
#match best security layer available
|
||||
if not self._serverPrivateKeyFileName is None and not self._serverCertificateFileName is None:
|
||||
self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_SSL
|
||||
self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_RDP
|
||||
else:
|
||||
self._selectedProtocol = self._requestedProtocol & Protocols.PROTOCOL_RDP
|
||||
|
||||
|
||||
Reference in New Issue
Block a user