b3aff3e4391f634171c72da7fdacf63127877285
[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 Enum
28
29
30 ValidationLevel = Enum(
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 == str(level):
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     # XXX implement key signature checking (#6120)
64
65     # First contact
66     if old_key is None:
67         return True
68
69     # An update of the same key
70     if new_key.fingerprint == old_key.fingerprint:
71         return True
72
73     # Manually verified fingerprint
74     if new_key.validation == ValidationLevel.Fingerprint:
75         return True
76
77     # Expired key and higher validation level
78     if (old_key.expiry_date is not None and
79             old_key.expiry_date < datetime.now() and
80             new_key.validation >= old_key.validation):
81         return True
82
83     # No expiration date and higher validation level
84     if (old_key.expiry_date is None and
85             new_key.validation > old_key.validation):
86         return True
87
88     # Not successfully used and strict high validation level
89     if (not (old_key.sign_used and old_key.encr_used) and
90             new_key.validation > old_key.validation):
91         return True
92
93     return False