[Python-modules-commits] [dkimpy] 01/04: Import dkimpy_0.6.2.orig.tar.gz

Scott Kitterman kitterman at moszumanska.debian.org
Sat Jun 10 20:46:47 UTC 2017


This is an automated email from the git hooks/post-receive script.

kitterman pushed a commit to branch master
in repository dkimpy.

commit 0886ac4ddee8d88ed509a9030b127dd58dc7a408
Author: Scott Kitterman <scott at kitterman.com>
Date:   Sat Jun 10 16:43:47 2017 -0400

    Import dkimpy_0.6.2.orig.tar.gz
---
 ChangeLog               |  12 ++++++++++++
 PKG-INFO                |   2 +-
 README                  |  14 ++++++++------
 dkim/.__init__.py.swo   | Bin 24576 -> 0 bytes
 dkim/__init__.py        |  35 +++++++++++++++++++----------------
 dkim/crypto.py          |  14 +++++++-------
 dkim/tests/test_dkim.py |  24 ++++++++++++++++++++++--
 dkim/util.py            |   2 +-
 setup.py                |   2 +-
 9 files changed, 71 insertions(+), 34 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a93a42f..98550bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2017-05-30 Version 0.6.2
+    - Fixed problem with header folding that caused the first line to be
+      folded too long (Updated test test_add_body_length since l= tag is no
+      longer at the beginning of a line)
+    - Fixed python3.4 string interpolation issue
+    - Fix some byte casting issues & typos
+    - Add test case for verification when should headers are signed
+    - Check and update references:
+      * Replace RFC 4871 withRFC 6376
+      * Replaace RFC 3447 with RFC 8017
+      * Add mention of DCRUP working group addressing key length issues
+
 2017-01-27 Version 0.6.1
     - Fixed python3 dns lookup issue
     - Fixed arcverify.py issue
diff --git a/PKG-INFO b/PKG-INFO
index 3d14410..9a01abd 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: dkimpy
-Version: 0.6.1
+Version: 0.6.2
 Summary: DKIM (DomainKeys Identified Mail)
 Home-page: https://launchpad.net/dkimpy
 Author: Scott Kitterman
diff --git a/README b/README
index 79686d2..1807c39 100644
--- a/README
+++ b/README
@@ -11,14 +11,13 @@ signing and verification.
 
 VERSION
 
-This is dkimpy 0.6.1.
+This is dkimpy 0.6.2.
 
 REQUIREMENTS
 
- - Python 2.x >= 2.7, or Python 3.x >= 3.5.  For use with DKIM, earlier
-   python3 versions will work.  ARC tests fail with python3.4.  Recent
-   versions have not been tested on python < 2.7 or python3 < 3.4, but may
-   still work on python2.6 and python 3.1 - 3.3.
+ - Python 2.x >= 2.7, or Python 3.x >= 3.4.  Recent versions have not been
+   tested on python < 2.7 or python3 < 3.4, but may still work on python2.6
+   and python 3.1 - 3.3.
  - dnspython or pydns. dnspython is preferred if both are present.
 
 INSTALLATION
@@ -62,7 +61,10 @@ python2.7 ./testarc.py validate runners/arcverifytest.py
 The reason for the test failure is that the ARC specification (as of 20170120)
 sets the minimum key size to 512 bits.  This is operationally inappropriate,
 so dkimpy sets the default minkey=1024, the same as is used for DKIM.  This
-can be overridden, but that is not recommended.
+can be overridden, but that is not recommended.  The minimum key size
+requirement for DKIM (and thus ARC) is in the process of being updated to
+require at least a 1024 bit key.  Information about the status of this effort
+is at https://datatracker.ietf.org/doc/draft-ietf-dcrup-dkim-usage/
 
 USAGE
 
diff --git a/dkim/.__init__.py.swo b/dkim/.__init__.py.swo
deleted file mode 100644
index 5c2a0cf..0000000
Binary files a/dkim/.__init__.py.swo and /dev/null differ
diff --git a/dkim/__init__.py b/dkim/__init__.py
index 6e7d473..7d3b75b 100644
--- a/dkim/__init__.py
+++ b/dkim/__init__.py
@@ -299,7 +299,7 @@ def text(s):
     if type(s) is str: return s
     return s.encode('ascii')
 
-def fold(header):
+def fold(header, namelen=0):
     """Fold a header line into multiple crlf-separated lines at column 72.
 
     >>> text(fold(b'foo'))
@@ -318,14 +318,18 @@ def fold(header):
         i += 3
         pre = header[:i]
         header = header[i:]
-    while len(header) > 72:
-        i = header[:72].rfind(b" ")
+    # 72 is the max line length we actually want, but the header field name
+    # has to fit in the first line too (See Debian Bug #863690).
+    maxleng = 72 - namelen
+    while len(header) > maxleng:
+        i = header[:maxleng].rfind(b" ")
         if i == -1:
-            j = 72
+            j = maxleng
         else:
             j = i + 1
         pre += header[:j] + b"\r\n "
         header = header[j:]
+        namelen = 0
     return pre + header
 
 def load_pk_from_dns(name, dnsfunc=get_txt):
@@ -366,9 +370,9 @@ class DomainSigner(object):
         raise ParameterError(
             "Unsupported signature algorithm: "+signature_algorithm)
     self.signature_algorithm = signature_algorithm
-    #: Header fields which should be signed.  Default from RFC4871
+    #: Header fields which should be signed.  Default as suggested by RFC6376
     self.should_sign = set(DKIM.SHOULD)
-    #: Header fields which should not be signed.  The default is from RFC4871.
+    #: Header fields which should not be signed.  The default is from RFC6376.
     #: Attempting to sign these headers results in an exception.
     #: If it is necessary to sign one of these, it must be removed
     #: from this list first.
@@ -385,18 +389,18 @@ class DomainSigner(object):
   #: @since: 0.5
   FROZEN = (b'from',b'date',b'subject')
 
-  #: The rfc4871 recommended header fields to sign
+  #: The rfc6376 recommended header fields to sign
   #: @since: 0.5
   SHOULD = (
     b'sender', b'reply-to', b'subject', b'date', b'message-id', b'to', b'cc',
     b'mime-version', b'content-type', b'content-transfer-encoding',
-    b'content-id', b'content- description', b'resent-date', b'resent-from',
+    b'content-id', b'content-description', b'resent-date', b'resent-from',
     b'resent-sender', b'resent-to', b'resent-cc', b'resent-message-id',
-    b'in-reply-to', 'references', b'list-id', b'list-help', b'list-unsubscribe',
+    b'in-reply-to', b'references', b'list-id', b'list-help', b'list-unsubscribe',
     b'list-subscribe', b'list-post', b'list-owner', b'list-archive'
   )
 
-  #: The rfc4871 recommended header fields not to sign.
+  #: The rfc6376 recommended header fields not to sign.
   #: @since: 0.5
   SHOULD_NOT = (
     b'return-path',b'received',b'comments',b'keywords',b'bcc',b'resent-bcc',
@@ -485,7 +489,7 @@ class DomainSigner(object):
 
     header_value = b"; ".join(b"=".join(x) for x in fields)
     if not standardize:
-      header_value = fold(header_value)
+      header_value = fold(header_value, namelen=len(header_name))
     header_value = RE_BTAG.sub(b'\\1',header_value)
     header = (header_name, b' ' + header_value)
     h = HashThrough(self.hasher())
@@ -508,9 +512,9 @@ class DomainSigner(object):
     idx = [i for i in range(len(fields)) if fields[i][0] == b'b'][0]
     fields[idx] = (b'b', base64.b64encode(bytes(sig2)))
     header_value = b"; ".join(b"=".join(x) for x in fields) + b"\r\n"
-    
+
     if not standardize:
-      header_value = fold(header_value)
+      header_value = fold(header_value, namelen=len(header_name))
 
     return header_value
 
@@ -656,7 +660,7 @@ class DKIM(DomainSigner):
         (b'c', canon_policy.to_c_value()),
         (b'd', domain),
         (b'i', identity or b"@"+domain),
-        length and (b'l', len(body)),
+        length and (b'l', str(len(body)).encode('ascii')),
         (b'q', b"dns/txt"),
         (b's', selector),
         (b't', str(int(time.time())).encode('ascii')),
@@ -810,7 +814,7 @@ class ARC(DomainSigner):
     arc_headers = [y for x,y in arc_headers_w_instance]
 
     # Compute ARC-Authentication-Results
-    aar_value = b"i=%d; %s" % (instance, auth_results)
+    aar_value = ("i=%d; " % instance).encode('utf-8') + auth_results
     if aar_value[-1] != b'\n': aar_value += b'\r\n'
 
     new_arc_set.append(b"ARC-Authentication-Results: " + aar_value)
@@ -1080,4 +1084,3 @@ def arc_verify(message, logger=None, dnsfunc=get_txt, minkey=1024):
         if logger is not None:
             logger.error("%s" % x)
         return CV_Fail, [], "%s" % x
-
diff --git a/dkim/crypto.py b/dkim/crypto.py
index 7ab43f3..c46c97a 100644
--- a/dkim/crypto.py
+++ b/dkim/crypto.py
@@ -83,7 +83,7 @@ HASH_ALGORITHMS = {
     b'rsa-sha256': hashlib.sha256,
     }
 
-# These values come from RFC 3447, section 9.2 Notes, page 43.
+# These values come from RFC 8017, section 9.2 Notes, page 46.
 HASH_ID_MAP = {
     'sha1': b"\x2b\x0e\x03\x02\x1a",
     'sha256': b"\x60\x86\x48\x01\x65\x03\x04\x02\x01",
@@ -104,7 +104,7 @@ def parse_public_key(data):
     """Parse an RSA public key.
 
     @param data: DER-encoded X.509 subjectPublicKeyInfo
-        containing an RFC3447 RSAPublicKey.
+        containing an RFC8017 RSAPublicKey.
     @return: RSA public key
     """
     try:
@@ -123,7 +123,7 @@ def parse_public_key(data):
 def parse_private_key(data):
     """Parse an RSA private key.
 
-    @param data: DER-encoded RFC3447 RSAPrivateKey.
+    @param data: DER-encoded RFC8017 RSAPrivateKey.
     @return: RSA private key
     """
     try:
@@ -147,7 +147,7 @@ def parse_private_key(data):
 def parse_pem_private_key(data):
     """Parse a PEM RSA private key.
 
-    @param data: RFC3447 RSAPrivateKey in PEM format.
+    @param data: RFC8017 RSAPrivateKey in PEM format.
     @return: RSA private key
     """
     m = re.search(b"--\n(.*?)\n--", data, re.DOTALL)
@@ -161,7 +161,7 @@ def parse_pem_private_key(data):
 
 
 def EMSA_PKCS1_v1_5_encode(hash, mlen):
-    """Encode a digest with RFC3447 EMSA-PKCS1-v1_5.
+    """Encode a digest with RFC8017 EMSA-PKCS1-v1_5.
 
     @param hash: hash object to encode
     @param mlen: desired message length
@@ -247,7 +247,7 @@ def rsa_encrypt(message, pk, mlen):
 
 
 def RSASSA_PKCS1_v1_5_sign(hash, private_key):
-    """Sign a digest with RFC3447 RSASSA-PKCS1-v1_5.
+    """Sign a digest with RFC8017 RSASSA-PKCS1-v1_5.
 
     @param hash: hash object to sign
     @param private_key: private key data
@@ -259,7 +259,7 @@ def RSASSA_PKCS1_v1_5_sign(hash, private_key):
 
 
 def RSASSA_PKCS1_v1_5_verify(hash, signature, public_key):
-    """Verify a digest signed with RFC3447 RSASSA-PKCS1-v1_5.
+    """Verify a digest signed with RFC8017 RSASSA-PKCS1-v1_5.
 
     @param hash: hash object to check
     @param signature: signed digest byte string
diff --git a/dkim/tests/test_dkim.py b/dkim/tests/test_dkim.py
index d721d78..3962a72 100644
--- a/dkim/tests/test_dkim.py
+++ b/dkim/tests/test_dkim.py
@@ -16,6 +16,7 @@
 #
 # Copyright (c) 2011 William Grant <me at williamgrant.id.au>
 
+import email
 import os.path
 import unittest
 import time
@@ -87,6 +88,25 @@ Y+vtSBczUiKERHv1yRbcaQtZFh5wtiRrN04BLUTD21MycBX5jYchHjPY/wIDAQAB"""
                 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc)
                 self.assertTrue(res)
 
+    def test_simple_signature(self):
+        # A message verifies after being signed with SHOULD headers
+        for header_algo in (b"simple", b"relaxed"):
+             for body_algo in (b"simple", b"relaxed"):
+                sig = dkim.sign(
+                    self.message, b"test", b"example.com", self.key,
+                    canonicalize=(header_algo, body_algo),
+                    include_headers=(b'from',) + dkim.DKIM.SHOULD)
+                res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc)
+                self.assertTrue(res)
+
+    def test_add_body_length(self):
+        sig = dkim.sign(
+            self.message, b"test", b"example.com", self.key, length=True)
+        msg = email.message_from_string(self.message.decode('utf-8'))
+        self.assertIn('; l=%s' % len(msg.get_payload() + '\n'), sig.decode('utf-8'))
+        res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc)
+        self.assertTrue(res)
+
     def test_altered_body_fails(self):
         # An altered body fails verification.
         for header_algo in (b"simple", b"relaxed"):
@@ -143,7 +163,7 @@ b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==
         # sig_value with empty b= before hashing, and then appends the
         # signature.  So folding dkim_header again adds FWS to
         # the b= tag only.  This should be ignored even with
-        # simple canonicalization.  
+        # simple canonicalization.
         # http://tools.ietf.org/html/rfc4871#section-3.5
         signed = dkim.fold(dkim_header) + sample_msg
         result = dkim.verify(signed,dnsfunc=self.dnsfunc,
@@ -164,7 +184,7 @@ b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==
         dv = dkim.DKIM(message)
         res = dv.verify(dnsfunc=self.dnsfunc)
         self.assertTrue(res)
-    	
+
     def test_extra_headers(self):
         # <https://bugs.launchpad.net/dkimpy/+bug/737311>
         # extra headers above From caused failure
diff --git a/dkim/util.py b/dkim/util.py
index a0545b0..3d1f722 100644
--- a/dkim/util.py
+++ b/dkim/util.py
@@ -51,7 +51,7 @@ class InvalidTagSpec(InvalidTagValueList):
 def parse_tag_value(tag_list):
     """Parse a DKIM Tag=Value list.
 
-    Interprets the syntax specified by RFC4871 section 3.2.
+    Interprets the syntax specified by RFC6376 section 3.2.
     Assumes that folding whitespace is already unfolded.
 
     @param tag_list: A bytes string containing a DKIM Tag=Value list.
diff --git a/setup.py b/setup.py
index 5bb6d5c..f26faca 100644
--- a/setup.py
+++ b/setup.py
@@ -24,7 +24,7 @@
 from distutils.core import setup
 import os
 
-version = "0.6.1"
+version = "0.6.2"
 
 setup(
     name = "dkimpy",

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/dkimpy.git



More information about the Python-modules-commits mailing list