Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

# -*- coding: utf-8 -*- 

""" 

Decryption class of ArcLink/WebDC client for ObsPy. 

 

.. seealso:: http://www.seiscomp3.org/wiki/doc/applications/arclink-encryption 

 

:copyright: 

    The ObsPy Development Team (devs@obspy.org) 

:license: 

    GNU Lesser General Public License, Version 3 

    (http://www.gnu.org/copyleft/lesser.html) 

""" 

 

try: 

    from M2Crypto import EVP 

    hasM2Crypto = True 

except ImportError: 

    hasM2Crypto = False 

 

 

class SSLWrapper: 

    """ 

    """ 

    def __init__(self, password): 

        if not hasM2Crypto: 

            raise Exception("Module M2Crypto was not found on this system.") 

        self._cypher = None 

        self._password = None 

        if password is None: 

            raise Exception('Password should not be Empty') 

        else: 

            self._password = password 

 

    def update(self, chunk): 

        if self._cypher is None: 

            if len(chunk) < 16: 

                raise Exception('Invalid first chunk (Size < 16).') 

            if chunk[0:8] != "Salted__": 

                raise Exception('Invalid first chunk (expected: Salted__') 

            [key, iv] = self._getKeyIv(self._password, chunk[8:16]) 

            self._cypher = EVP.Cipher('des_cbc', key, iv, 0) 

            chunk = chunk[16:] 

        if len(chunk) > 0: 

            return self._cypher.update(chunk) 

        else: 

            return '' 

 

    def final(self): 

        if self._cypher is None: 

            raise Exception('Wrapper has not started yet.') 

        return self._cypher.final() 

 

    def _getKeyIv(self, password, salt=None, size=8): 

        chunk = None 

        key = "" 

        iv = "" 

        while True: 

            hash = EVP.MessageDigest('md5') 

            if (chunk is not None): 

                hash.update(chunk) 

            hash.update(password) 

            if (salt is not None): 

                hash.update(salt) 

            chunk = hash.final() 

            i = 0 

            if len(key) < size: 

                i = min(size - len(key), len(chunk)) 

                key += chunk[0:i] 

            if len(iv) < size and i < len(chunk): 

                j = min(size - len(iv), len(chunk) - i) 

                iv += chunk[i:i + j] 

            if (len(key) == size and len(iv) == size): 

                break 

        return [key, iv]