summaryrefslogtreecommitdiff
path: root/src/leap/keymanager/validation.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/keymanager/validation.py')
-rw-r--r--src/leap/keymanager/validation.py94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/leap/keymanager/validation.py b/src/leap/keymanager/validation.py
new file mode 100644
index 0000000..6dceb78
--- /dev/null
+++ b/src/leap/keymanager/validation.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+# __init__.py
+# Copyright (C) 2014 LEAP
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Validation levels implementation for key managment.
+
+See:
+ https://lists.riseup.net/www/arc/leap-discuss/2014-09/msg00000.html
+"""
+
+
+from datetime import datetime
+from enum import Enum
+
+
+ValidationLevel = Enum(
+ "Weak_Chain",
+ "Provider_Trust",
+ "Provider_Endorsement",
+ "Third_Party_Endorsement",
+ "Third_Party_Consensus",
+ "Historically_Auditing",
+ "Known_Key",
+ "Fingerprint")
+
+
+def toValidationLevel(value):
+ """
+ Convert a string representation of a validation level into
+ C{ValidationLevel}
+
+ :param value: validation level
+ :type value: str
+ :rtype: ValidationLevel
+ :raises ValueError: if C{value} is not a validation level
+ """
+ for level in ValidationLevel:
+ if value == str(level):
+ return level
+ raise ValueError("Not valid validation level: %s" % (value,))
+
+
+def can_upgrade(new_key, old_key):
+ """
+ :type new_key: EncryptionKey
+ :type old_key: EncryptionKey
+ :rtype: bool
+ """
+ # XXX not succesfully used and strict high validation level (#6211)
+ # XXX implement key signature checking (#6120)
+
+ # First contact
+ if old_key is None:
+ return True
+
+ if new_key.address != old_key.address:
+ # XXX how do we map multiple IDs? (#6212)
+ return False
+
+ # An update of the same key
+ if new_key.fingerprint == old_key.fingerprint:
+ # XXX wich one is newer? is that a downgrade attack? (#6210)
+ return True
+
+ # Manually verified fingerprint
+ if new_key.validation == ValidationLevel.Fingerprint:
+ return True
+
+ # Expired key and higher validation level
+ if old_key.expiry_date:
+ old_expiry_date = datetime.fromtimestamp(int(old_key.expiry_date))
+ if (old_expiry_date < datetime.now() and
+ new_key.validation >= old_key.validation):
+ return True
+
+ # No expiration date and higher validation level
+ elif new_key.validation >= old_key.validation:
+ return True
+
+ return False