Esempio n. 1
0
    def __init__(self, data=None, password=None):
        if data is None:
            return

        TlsStructure.__init__(self, data)
        if len(data) != TackKeyFile.LENGTH:
            raise SyntaxError(
                "Key File is the wrong size. Is %s and should be %s." %
                (len(data), TackKeyFile.LENGTH))

        self.version = self.getInt(1)

        if self.version != 1:
            raise SyntaxError("Bad version in Key File")

        self.iter_count = self.getInt(4)
        self.salt = self.getBytes(16)
        self.ciphertext = self.getBytes(32)
        self.public_key = ECPublicKey.create(self.getBytes(64))
        self.mac = self.getBytes(32)

        if password is not None:
            rawPrivateKey = self._decrypt(password)
            self.private_key = ECPrivateKey.create(rawPrivateKey,
                                                   self.public_key.getRawKey())
Esempio n. 2
0
    def __init__(self, data=None):
        TlsStructure.__init__(self, data)

        if data is not None and len(data) != TackBreakSig.LENGTH:
            raise SyntaxError(
                "Break signature is the wrong size. Is %s and should be %s." %
                (len(data), TackBreakSig.LENGTH))

        if data is not None:
            self.public_key = ECPublicKey(self.getBytes(64))
            self.signature = self.getBytes(64)

            if not self._verifySignature():
                raise SyntaxError("Signature verification failure")

            if self.index != len(data):
                raise SyntaxError("Excess bytes in TACK_Break_Sig")
Esempio n. 3
0
    def generateECKeyPair(self):
        # Generate M2Crypto.EC.EC object
        ec = EC.gen_params(EC.NID_X9_62_prime256v1)
        ec.gen_key()

        rawPrivateKey, rawPublicKey = self._constructRawKeysFromEc(ec)

        return ECPublicKey(rawPublicKey,
                           ec), ECPrivateKey(rawPrivateKey, rawPublicKey, ec)
Esempio n. 4
0
    def getSignature(self, data):
        # Produce ASN.1 signature
        hash = Digest.SHA256(data)
        asn1SigBytes = self.ec.sign_dsa_asn1(hash)

        # Convert stupid ASN.1 signature into 64-byte signature
        # Double-check before returning
        sigBytes = self._convertToRawSignature(asn1SigBytes)

        assert (ECPublicKey(self.rawPublicKey, self.ec).verify(data, sigBytes))
        return sigBytes
Esempio n. 5
0
    def __init__(self, data=None, password=None):
        TlsStructure.__init__(self, data)
        if data is not None:
            self.version = self.getInt(1)

            if self.version != 1:
                raise SyntaxError("Bad version in Secret File")

            self.password = password
            self.iter_count = self.getInt(4)
            self.salt = self.getBytes(16)
            self.ciphertext = self.getBytes(32)
            self.public_key = ECPublicKey(self.getBytes(64))
            self.mac = bytearray(self.getBytes(32))

            if self.password is not None:
                rawPrivateKey = self._decryptKey(password, self.salt,
                                                 self.ciphertext,
                                                 self.iter_count,
                                                 self.public_key, self.mac)
                self.private_key = ECPrivateKey(rawPrivateKey,
                                                self.public_key.getRawKey())
Esempio n. 6
0
    def __init__(self, data=None):
        if data is None:
            return

        TlsStructure.__init__(self, data)
        if len(data) != TackBreakSig.LENGTH:
            raise SyntaxError("Break signature is the wrong size. Is %s and should be %s." % (len(data), TackBreakSig.LENGTH))

        self.public_key = ECPublicKey.create(self.getBytes(64))
        self.signature  = self.getBytes(64)
            
        if not self.verifySignature():
            raise SyntaxError("TACK_Break_Sig has bad signature")
Esempio n. 7
0
    def __init__(self, data=None):
        TlsStructure.__init__(self, data)
        if data is not None:
            self.public_key     = ECPublicKey(self.getBytes(64))
            self.min_generation = self.getInt(1)
            self.generation     = self.getInt(1)
            self.expiration     = self.getInt(4)
            self.target_hash    = self.getBytes(32)
            self.signature      = self.getBytes(64)

            if not self._verifySignature():
                raise SyntaxError("Signature verification failure")
            if self.index != len(data):
                raise SyntaxError("Excess bytes in TACK")
Esempio n. 8
0
    def __init__(self, data=None):
        TlsStructure.__init__(self, data)

        if data is not None and len(data) != TackBreakSig.LENGTH:
            raise SyntaxError("Break signature is the wrong size. Is %s and should be %s." % (len(data), TackBreakSig.LENGTH))

        if data is not None:
            self.public_key = ECPublicKey(self.getBytes(64))
            self.signature  = self.getBytes(64)

            if not self._verifySignature():
                raise SyntaxError("Signature verification failure")

            if self.index != len(data):
                raise SyntaxError("Excess bytes in TACK_Break_Sig")
Esempio n. 9
0
    def __init__(self, data=None, password=None):
        TlsStructure.__init__(self, data)
        if data is not None:
            self.version = self.getInt(1)

            if self.version != 1:
                raise SyntaxError("Bad version in Secret File")

            self.password    = password
            self.iter_count  = self.getInt(4)
            self.salt        = self.getBytes(16)
            self.ciphertext  = self.getBytes(32)
            self.public_key  = ECPublicKey(self.getBytes(64))
            self.mac         = bytearray(self.getBytes(32))

            if self.password is not None:
                rawPrivateKey = self._decryptKey(password, self.salt, self.ciphertext,
                                                 self.iter_count, self.public_key, self.mac)
                self.private_key = ECPrivateKey(rawPrivateKey, self.public_key.getRawKey())
Esempio n. 10
0
    def __init__(self, data=None):
        if data is None:
            return

        TlsStructure.__init__(self, data)
        if len(data) != Tack.LENGTH:
            raise SyntaxError("Tack is the wrong size. Is %s and should be %s" % (len(data), Tack.LENGTH))        

        self.public_key     = ECPublicKey.create(self.getBytes(64))
        self.min_generation = self.getInt(1)
        self.generation     = self.getInt(1)
        self.expiration     = self.getInt(4)
        self.target_hash    = self.getBytes(32)
        self.signature      = self.getBytes(64)

        if self.generation < self.min_generation:
            raise SyntaxError("Generation less than min_generation")
            
        if not self.verifySignature():
            raise SyntaxError("Tack has bad signature")
Esempio n. 11
0
    def __init__(self, data=None, password=None):
        if data is None:
            return
        
        TlsStructure.__init__(self, data)
        if len(data) != TackKeyFile.LENGTH:
            raise SyntaxError("Key File is the wrong size. Is %s and should be %s." % (len(data), TackKeyFile.LENGTH))
            
        self.version = self.getInt(1)

        if self.version != 1:
            raise SyntaxError("Bad version in Key File")

        self.iter_count  = self.getInt(4)
        self.salt        = self.getBytes(16)
        self.ciphertext  = self.getBytes(32)
        self.public_key  = ECPublicKey.create(self.getBytes(64))
        self.mac         = self.getBytes(32)

        if password is not None:
            rawPrivateKey = self._decrypt(password)
            self.private_key = ECPrivateKey.create(rawPrivateKey, self.public_key.getRawKey())
Esempio n. 12
0
    def __init__(self, data=None):
        if data is None:
            return

        TlsStructure.__init__(self, data)
        if len(data) != Tack.LENGTH:
            raise SyntaxError(
                "Tack is the wrong size. Is %s and should be %s" %
                (len(data), Tack.LENGTH))

        self.public_key = ECPublicKey.create(self.getBytes(64))
        self.min_generation = self.getInt(1)
        self.generation = self.getInt(1)
        self.expiration = self.getInt(4)
        self.target_hash = self.getBytes(32)
        self.signature = self.getBytes(64)

        if self.generation < self.min_generation:
            raise SyntaxError("Generation less than min_generation")

        if not self.verifySignature():
            raise SyntaxError("Tack has bad signature")
Esempio n. 13
0
class TackKeyFile(TlsStructure):
    LENGTH = 149 # length of keyfile in bytes

    def __init__(self, data=None, password=None):
        TlsStructure.__init__(self, data)
        if data is not None:
            self.version = self.getInt(1)

            if self.version != 1:
                raise SyntaxError("Bad version in Secret File")

            self.password    = password
            self.iter_count  = self.getInt(4)
            self.salt        = self.getBytes(16)
            self.ciphertext  = self.getBytes(32)
            self.public_key  = ECPublicKey(self.getBytes(64))
            self.mac         = bytearray(self.getBytes(32))

            if self.password is not None:
                rawPrivateKey = self._decryptKey(password, self.salt, self.ciphertext,
                                                 self.iter_count, self.public_key, self.mac)
                self.private_key = ECPrivateKey(rawPrivateKey, self.public_key.getRawKey())

    @classmethod
    def createRandom(cls, password):
        tackKeyFile            = cls()
        tackKeyFile.password   = password
        tackKeyFile.version    = 1
        tackKeyFile.iter_count = 8192
        tackKeyFile.salt       = bytearray(os.urandom(16))
        tackKeyFile.public_key, tackKeyFile.private_key = ECGenerator().generateECKeyPair()
        tackKeyFile.ciphertext, tackKeyFile.mac         = tackKeyFile._encryptKey(password, tackKeyFile.salt,
                                                                                  tackKeyFile.iter_count,
                                                                                  tackKeyFile.public_key,
                                                                                  tackKeyFile.private_key)
        return tackKeyFile

    @classmethod
    def createFromPem(cls, pem, password):
        return cls(PEMDecoder(pem).getDecoded("TACK PRIVATE KEY"), password)

    def getPublicKey(self):
        return self.public_key

    def getPrivateKey(self):
        return self.private_key

    def serialize(self):
        w = TlsStructureWriter(TackKeyFile.LENGTH)
        w.add(self.version, 1)
        w.add(self.iter_count, 4)
        w.add(self.salt, 16)
        w.add(self.ciphertext, 32)
        w.add(self.public_key.getRawKey(), 64)
        w.add(self.mac, 32)
        assert(w.index == len(w.bytes)) # did we fill entire bytearray?

        return w.getBytes()

    def serializeAsPem(self):
        return PEMEncoder(self.serialize()).getEncoded("TACK PRIVATE KEY")

    def _encryptKey(self, password, salt, iter_count, public_key, private_key):
        encKey, authKey = self._deriveKeys(password, salt, iter_count)
        ciphertext      = AES(encKey, bytearray(16)).encrypt(private_key.getRawKey())
        macData         = ciphertext + public_key.getRawKey()
        mac             = Digest.HMAC_SHA256(authKey, macData)
        return ciphertext, mac


    def _decryptKey(self, password, salt, ciphertext, iter_count, public_key, mac):
        encKey, authKey = self._deriveKeys(password, salt, iter_count)
        macData         = ciphertext + public_key.getRawKey()
        calcMac         = Digest.HMAC_SHA256(authKey, macData)

        if not Util.constTimeCompare(calcMac, mac):
            raise InvalidPasswordException("Bad password")

        return AES(encKey, bytearray(16)).decrypt(ciphertext)

    # Uses PBKDF2, then HMAC-SHA256 as PRF to derive independent 32-byte keys
    def _deriveKeys(self, password, salt, iter_count):
        assert(iter_count>0)
        masterKey = PBKDF2.hmac_sha256(password, salt, iter_count)
        encKey    = Digest.HMAC_SHA256(masterKey, bytearray([1]))
        authKey   = Digest.HMAC_SHA256(masterKey, bytearray([2]))
        return encKey, authKey

    def __str__(self):
        return """TACK ID        = %s\n""" % str(self.public_key)
Esempio n. 14
0
class TackBreakSig(TlsStructure):
    LENGTH = 128

    def __init__(self, data=None):
        TlsStructure.__init__(self, data)

        if data is not None and len(data) != TackBreakSig.LENGTH:
            raise SyntaxError(
                "Break signature is the wrong size. Is %s and should be %s." %
                (len(data), TackBreakSig.LENGTH))

        if data is not None:
            self.public_key = ECPublicKey(self.getBytes(64))
            self.signature = self.getBytes(64)

            if not self._verifySignature():
                raise SyntaxError("Signature verification failure")

            if self.index != len(data):
                raise SyntaxError("Excess bytes in TACK_Break_Sig")

    @classmethod
    def createFromPem(cls, data):
        return cls(PEMDecoder(data).getDecoded("TACK BREAK SIG"))

    @classmethod
    def createFromPemList(cls, data):
        """Parse a string containing a sequence of PEM Break Sigs.

        Raise a SyntaxError if input is malformed.
        """
        breakSigs = []
        bList = PEMDecoder(data).getDecodedList("TACK BREAK SIG")
        for b in bList:
            breakSigs.append(TackBreakSig(b))

        return breakSigs

    @classmethod
    def createFromParameters(cls, public_key, private_key):
        assert (len(public_key) == 64)
        tackBreakSig = cls()
        tackBreakSig.public_key = public_key
        tackBreakSig.signature = private_key.getSignature(
            bytearray("tack_break_sig", "ascii"))

        return tackBreakSig

    def serialize(self):
        """Return a bytearray containing the TACK_Break_Sig."""
        w = TlsStructureWriter(TackBreakSig.LENGTH)
        w.add(self.public_key.getRawKey(), 64)
        w.add(self.signature, 64)
        assert (w.index == len(w.bytes))
        return w.getBytes()

    def serializeAsPem(self):
        return PEMEncoder(self.serialize()).getEncoded("TACK BREAK SIG")

    def getTackId(self):
        return str(self.public_key)

    def _verifySignature(self):
        return self.public_key.verify(bytearray("tack_break_sig"),
                                      self.signature)

    def __str__(self):
        """Return a readable string describing this TACK_Break_Sig.
        Used by the "TACK view" command to display TACK objects."""
        return "Breaks TACK ID = %s\n" % self.getTackId()
Esempio n. 15
0
class Tack(TlsStructure):
    LENGTH =  166

    def __init__(self, data=None):
        TlsStructure.__init__(self, data)
        if data is not None:
            self.public_key     = ECPublicKey(self.getBytes(64))
            self.min_generation = self.getInt(1)
            self.generation     = self.getInt(1)
            self.expiration     = self.getInt(4)
            self.target_hash    = self.getBytes(32)
            self.signature      = self.getBytes(64)

            if not self._verifySignature():
                raise SyntaxError("Signature verification failure")
            if self.index != len(data):
                raise SyntaxError("Excess bytes in TACK")

    @classmethod
    def createFromPem(cls, pem):
        data = PEMDecoder(pem).getDecoded("TACK")

        if len(data) != Tack.LENGTH:
            raise SyntaxError("TACK is the wrong size. %s, should be %s" % (len(data), Tack.LENGTH))

        return cls(data)

    @classmethod
    def createFromParameters(cls, public_key, private_key, min_generation, generation, expiration, target_hash):
        assert(len(public_key.getRawKey()) == 64)
        assert(0 <= min_generation <= 255)
        assert(0 <= generation <= 255 and
               generation >= min_generation)
        assert(0 <= expiration <= 2**32-1)
        assert(len(target_hash) == 32)

        tack = cls()
        tack.public_key     = public_key
        tack.min_generation = min_generation
        tack.generation     = generation
        tack.expiration     = expiration
        tack.target_hash    = target_hash
        tack.signature      = private_key.getSignature(tack._getDataToSign())

        return tack

    def getTackId(self):
        return str(self.public_key)

    def serialize(self):
        writer = TlsStructureWriter(64)
        writer.add(self.signature, 64)
        return self._serializePrelude() + writer.getBytes()

    def serializeAsPem(self):
        return PEMEncoder(self.serialize()).getEncoded("TACK")

    def _serializePrelude(self):
        writer = TlsStructureWriter(Tack.LENGTH - 64)
        writer.add(self.public_key.getRawKey(), 64)
        writer.add(self.min_generation, 1)
        writer.add(self.generation, 1)
        writer.add(self.expiration, 4)
        writer.add(self.target_hash, 32)
        return writer.getBytes()

    def _getDataToSign(self):
        return bytearray("tack_sig", "ascii") + self._serializePrelude()

    def _verifySignature(self):
        bytesToVerify = self._getDataToSign()
        return self.public_key.verify(bytesToVerify, self.signature)

    def __str__(self):
        """Return a readable string describing this TACK.

        Used by the "TACK view" command to display TACK objects."""
        s =\
        """TACK ID        = %s
min_generation = %d
generation     = %d
expiration     = %s
target_hash    = %s\n""" %\
        (self.getTackId(),
         self.min_generation,
         self.generation,
         Time.posixTimeToStr(self.expiration*60),
         Util.writeBytes(self.target_hash))
        return s
Esempio n. 16
0
class TackKeyFile(TlsStructure):
    LENGTH = 149  # length of keyfile in bytes

    def __init__(self, data=None, password=None):
        TlsStructure.__init__(self, data)
        if data is not None:
            self.version = self.getInt(1)

            if self.version != 1:
                raise SyntaxError("Bad version in Secret File")

            self.password = password
            self.iter_count = self.getInt(4)
            self.salt = self.getBytes(16)
            self.ciphertext = self.getBytes(32)
            self.public_key = ECPublicKey(self.getBytes(64))
            self.mac = bytearray(self.getBytes(32))

            if self.password is not None:
                rawPrivateKey = self._decryptKey(password, self.salt,
                                                 self.ciphertext,
                                                 self.iter_count,
                                                 self.public_key, self.mac)
                self.private_key = ECPrivateKey(rawPrivateKey,
                                                self.public_key.getRawKey())

    @classmethod
    def createRandom(cls, password):
        tackKeyFile = cls()
        tackKeyFile.password = password
        tackKeyFile.version = 1
        tackKeyFile.iter_count = 8192
        tackKeyFile.salt = bytearray(os.urandom(16))
        tackKeyFile.public_key, tackKeyFile.private_key = ECGenerator(
        ).generateECKeyPair()
        tackKeyFile.ciphertext, tackKeyFile.mac = tackKeyFile._encryptKey(
            password, tackKeyFile.salt, tackKeyFile.iter_count,
            tackKeyFile.public_key, tackKeyFile.private_key)
        return tackKeyFile

    @classmethod
    def createFromPem(cls, pem, password):
        return cls(PEMDecoder(pem).getDecoded("TACK PRIVATE KEY"), password)

    def getPublicKey(self):
        return self.public_key

    def getPrivateKey(self):
        return self.private_key

    def serialize(self):
        w = TlsStructureWriter(TackKeyFile.LENGTH)
        w.add(self.version, 1)
        w.add(self.iter_count, 4)
        w.add(self.salt, 16)
        w.add(self.ciphertext, 32)
        w.add(self.public_key.getRawKey(), 64)
        w.add(self.mac, 32)
        assert (w.index == len(w.bytes))  # did we fill entire bytearray?

        return w.getBytes()

    def serializeAsPem(self):
        return PEMEncoder(self.serialize()).getEncoded("TACK PRIVATE KEY")

    def _encryptKey(self, password, salt, iter_count, public_key, private_key):
        encKey, authKey = self._deriveKeys(password, salt, iter_count)
        ciphertext = AES(encKey,
                         bytearray(16)).encrypt(private_key.getRawKey())
        macData = ciphertext + public_key.getRawKey()
        mac = Digest.HMAC_SHA256(authKey, macData)
        return ciphertext, mac

    def _decryptKey(self, password, salt, ciphertext, iter_count, public_key,
                    mac):
        encKey, authKey = self._deriveKeys(password, salt, iter_count)
        macData = ciphertext + public_key.getRawKey()
        calcMac = Digest.HMAC_SHA256(authKey, macData)

        if not Util.constTimeCompare(calcMac, mac):
            raise InvalidPasswordException("Bad password")

        return AES(encKey, bytearray(16)).decrypt(ciphertext)

    # Uses PBKDF2, then HMAC-SHA256 as PRF to derive independent 32-byte keys
    def _deriveKeys(self, password, salt, iter_count):
        assert (iter_count > 0)
        masterKey = PBKDF2.hmac_sha256(password, salt, iter_count)
        encKey = Digest.HMAC_SHA256(masterKey, bytearray([1]))
        authKey = Digest.HMAC_SHA256(masterKey, bytearray([2]))
        return encKey, authKey

    def __str__(self):
        return """TACK ID        = %s\n""" % str(self.public_key)
Esempio n. 17
0
class TackBreakSig(TlsStructure):
    LENGTH = 128

    def __init__(self, data=None):
        TlsStructure.__init__(self, data)

        if data is not None and len(data) != TackBreakSig.LENGTH:
            raise SyntaxError("Break signature is the wrong size. Is %s and should be %s." % (len(data), TackBreakSig.LENGTH))

        if data is not None:
            self.public_key = ECPublicKey(self.getBytes(64))
            self.signature  = self.getBytes(64)

            if not self._verifySignature():
                raise SyntaxError("Signature verification failure")

            if self.index != len(data):
                raise SyntaxError("Excess bytes in TACK_Break_Sig")

    @classmethod
    def createFromPem(cls, data):
        return cls(PEMDecoder(data).getDecoded("TACK BREAK SIG"))

    @classmethod
    def createFromPemList(cls, data):
        """Parse a string containing a sequence of PEM Break Sigs.

        Raise a SyntaxError if input is malformed.
        """
        breakSigs = []
        bList = PEMDecoder(data).getDecodedList("TACK BREAK SIG")
        for b in bList:
            breakSigs.append(TackBreakSig(b))

        return breakSigs

    @classmethod
    def createFromParameters(cls, public_key, private_key):
        assert(len(public_key) == 64)
        tackBreakSig            = cls()
        tackBreakSig.public_key = public_key
        tackBreakSig.signature  = private_key.getSignature(bytearray("tack_break_sig", "ascii"))

        return tackBreakSig

    def serialize(self):
        """Return a bytearray containing the TACK_Break_Sig."""
        w = TlsStructureWriter(TackBreakSig.LENGTH)
        w.add(self.public_key.getRawKey(), 64)
        w.add(self.signature, 64)
        assert(w.index == len(w.bytes))
        return w.getBytes()

    def serializeAsPem(self):
        return PEMEncoder(self.serialize()).getEncoded("TACK BREAK SIG")

    def getTackId(self):
        return str(self.public_key)

    def _verifySignature(self):
        return self.public_key.verify(bytearray("tack_break_sig"), self.signature)

    def __str__(self):
        """Return a readable string describing this TACK_Break_Sig.
        Used by the "TACK view" command to display TACK objects."""
        return "Breaks TACK ID = %s\n" % self.getTackId()