Port validation levels to enum34
[keymanager.git] / src / leap / keymanager / validation.py
1 # -*- coding: utf-8 -*-
2 # __init__.py
3 # Copyright (C) 2014 LEAP
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 """
19 Validation levels implementation for key managment.
20
21 See:
22     https://lists.riseup.net/www/arc/leap-discuss/2014-09/msg00000.html
23 """
24
25
26 from datetime import datetime
27 from enum import IntEnum
28
29
30 ValidationLevel = IntEnum("ValidationLevel",
31     "Weak_Chain "
32     "Provider_Trust "
33     "Provider_Endorsement "
34     "Third_Party_Endorsement "
35     "Third_Party_Consensus "
36     "Historically_Auditing "
37     "Known_Key "
38     "Fingerprint")
39
40
41 def toValidationLevel(value):
42     """
43     Convert a string representation of a validation level into
44     C{ValidationLevel}
45
46     :param value: validation level
47     :type value: str
48     :rtype: ValidationLevel
49     :raises ValueError: if C{value} is not a validation level
50     """
51     for level in ValidationLevel:
52         if value == level.name:
53             return level
54     raise ValueError("Not valid validation level: %s" % (value,))
55
56
57 def can_upgrade(new_key, old_key):
58     """
59     :type new_key: EncryptionKey
60     :type old_key: EncryptionKey
61     :rtype: bool
62     """
63     # First contact
64     if old_key is None:
65         return True
66
67     # An update of the same key
68     if new_key.fingerprint == old_key.fingerprint:
69         return True
70
71     # Manually verified fingerprint
72     if new_key.validation == ValidationLevel.Fingerprint:
73         return True
74
75     # Expired key and higher validation level
76     if (old_key.expiry_date is not None and
77             old_key.expiry_date < datetime.now() and
78             new_key.validation >= old_key.validation):
79         return True
80
81     # No expiration date and higher validation level
82     if (old_key.expiry_date is None and
83             new_key.validation > old_key.validation):
84         return True
85
86     # Not successfully used and strict high validation level
87     if (not (old_key.sign_used and old_key.encr_used) and
88             new_key.validation > old_key.validation):
89         return True
90
91     # New key signed by the old key
92     if old_key.key_id in new_key.signatures:
93         return True
94
95     return False