[tor-commits] [stem/master] Add support for v3 ed25519 certs.

atagar at torproject.org atagar at torproject.org
Sun Oct 6 02:07:34 UTC 2019


commit 3625cb184da353f0ae895a1b65e22d9e50dd5e14
Author: George Kadianakis <desnacked at riseup.net>
Date:   Mon Aug 26 14:48:29 2019 +0300

    Add support for v3 ed25519 certs.
---
 stem/descriptor/certificate.py | 58 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/stem/descriptor/certificate.py b/stem/descriptor/certificate.py
index 449e106c..470fa623 100644
--- a/stem/descriptor/certificate.py
+++ b/stem/descriptor/certificate.py
@@ -26,13 +26,16 @@ used to validate the key used to sign server descriptors.
   Purpose of Ed25519 certificate. As new certificate versions are added this
   enumeration will expand.
 
-  ==============  ===========
-  CertType        Description
-  ==============  ===========
-  **SIGNING**     signing a signing key with an identity key
-  **LINK_CERT**   TLS link certificate signed with ed25519 signing key
-  **AUTH**        authentication key signed with ed25519 signing key
-  ==============  ===========
+  ==============                     ===========
+  CertType                           Description
+  ==============                     ===========
+  **SIGNING**                        signing a signing key with an identity key
+  **LINK_CERT**                      TLS link certificate signed with ed25519 signing key
+  **AUTH**                           authentication key signed with ed25519 signing key
+  **HS_V3_DESC_SIGNING_KEY**         onion service v3 descriptor signing key cert (see rend-spec-v3.txt)
+  **HS_V3_INTRO_POINT_AUTH_KEY**     onion service v3 intro point authentication key cert (see rend-spec-v3.txt)
+  **HS_V3_INTRO_POINT_ENC_KEY**      onion service v3 intro point encryption key cert (see rend-spec-v3.txt)
+  ==============                     ===========
 
 .. data:: ExtensionType (enum)
 
@@ -70,7 +73,8 @@ ED25519_HEADER_LENGTH = 40
 ED25519_SIGNATURE_LENGTH = 64
 ED25519_ROUTER_SIGNATURE_PREFIX = b'Tor router descriptor signature v1'
 
-CertType = stem.util.enum.UppercaseEnum('SIGNING', 'LINK_CERT', 'AUTH')
+CertType = stem.util.enum.UppercaseEnum('SIGNING', 'LINK_CERT', 'AUTH',
+                                        "HS_V3_DESC_SIGNING_KEY", "HS_V3_INTRO_POINT_AUTH_KEY", "HS_V3_INTRO_POINT_ENC_KEY")
 ExtensionType = stem.util.enum.Enum(('HAS_SIGNING_KEY', 4),)
 ExtensionFlag = stem.util.enum.UppercaseEnum('AFFECTS_VALIDATION', 'UNKNOWN')
 
@@ -158,8 +162,14 @@ class Ed25519CertificateV1(Ed25519Certificate):
       self.type = CertType.AUTH
     elif cert_type == 7:
       raise ValueError('Ed25519 certificate cannot have a type of 7. This is reserved for RSA identity cross-certification.')
+    elif cert_type == 8: # see rend-spec-v3.txt appendix E for these defintions
+      self.type = CertType.HS_V3_DESC_SIGNING_KEY
+    elif cert_type == 9:
+      self.type = CertType.HS_V3_INTRO_POINT_AUTH_KEY
+    elif cert_type == 0x0B:
+      self.type = CertType.HS_V3_INTRO_POINT_ENC_KEY
     else:
-      raise ValueError("BUG: Ed25519 certificate type is decoded from one byte. It shouldn't be possible to have a value of %i." % cert_type)
+      raise ValueError("Ed25519 certificate type is an unknown value %i." % cert_type)
 
     # expiration time is in hours since epoch
     try:
@@ -214,6 +224,9 @@ class Ed25519CertificateV1(Ed25519Certificate):
 
     return datetime.datetime.now() > self.expiration
 
+  # ATAGAR XXX certificates are generic and not just for descriptor, however
+  # this function assumes they are. this needs to be moved to the descriptor
+  # module. the new verify() function is more generic and should be used.
   def validate(self, server_descriptor):
     """
     Validates our signing key and that the given descriptor content matches its
@@ -269,3 +282,30 @@ class Ed25519CertificateV1(Ed25519Certificate):
       verify_key.verify(signature_bytes, descriptor_sha256_digest)
     except InvalidSignature:
       raise ValueError('Descriptor Ed25519 certificate signature invalid (Signature was forged or corrupt)')
+
+  def get_signing_key(self):
+    """
+    Get the signing key for this certificate. This is included in the extensions.
+    WARNING: This is the key that signed the certificate, not the key that got
+    certified.
+
+    :returns: Raw bytes of an ed25519 key.
+
+    :raises: **ValueError** if the signing key cannot be found.
+    """
+    signing_key_extension = None
+
+    for extension in self.extensions:
+      if extension.type == ExtensionType.HAS_SIGNING_KEY:
+        signing_key_extension = extension
+        break
+
+    if not signing_key_extension:
+      raise ValueError('Signing key extension could not be found')
+
+    if (len(signing_key_extension.data) != 32):
+      raise ValueError('Signing key extension has malformed key')
+
+    return signing_key_extension.data
+
+





More information about the tor-commits mailing list