diff -Nru dkimpy-0.6.1/ChangeLog dkimpy-0.6.2/ChangeLog --- dkimpy-0.6.1/ChangeLog 2017-01-27 23:43:58.000000000 +0000 +++ dkimpy-0.6.2/ChangeLog 2017-05-31 12:59:35.000000000 +0000 @@ -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 -Nru dkimpy-0.6.1/debian/changelog dkimpy-0.6.2/debian/changelog --- dkimpy-0.6.1/debian/changelog 2017-03-02 22:16:36.000000000 +0000 +++ dkimpy-0.6.2/debian/changelog 2017-06-10 20:44:45.000000000 +0000 @@ -1,3 +1,10 @@ +dkimpy (0.6.2-1) unstable; urgency=medium + + * New upstream release + - Bug fixes, including Closes: #863690 + + -- Scott Kitterman Sat, 10 Jun 2017 16:44:45 -0400 + dkimpy (0.6.1-1) unstable; urgency=medium * New upstream release: (Closes: #856609, #856611, #856613) diff -Nru dkimpy-0.6.1/debian/.git-dpm dkimpy-0.6.2/debian/.git-dpm --- dkimpy-0.6.1/debian/.git-dpm 2017-03-02 22:13:54.000000000 +0000 +++ dkimpy-0.6.2/debian/.git-dpm 2017-06-10 20:43:48.000000000 +0000 @@ -1,11 +1,11 @@ # see git-dpm(1) from git-dpm package -ec31673f633ff352f9bb1e883a47764f6a344ff3 -ec31673f633ff352f9bb1e883a47764f6a344ff3 -ec31673f633ff352f9bb1e883a47764f6a344ff3 -ec31673f633ff352f9bb1e883a47764f6a344ff3 -dkimpy_0.6.1.orig.tar.gz -e2465cc62171927779d36cc3fd93e177009ba26d -42744 +0886ac4ddee8d88ed509a9030b127dd58dc7a408 +0886ac4ddee8d88ed509a9030b127dd58dc7a408 +0886ac4ddee8d88ed509a9030b127dd58dc7a408 +0886ac4ddee8d88ed509a9030b127dd58dc7a408 +dkimpy_0.6.2.orig.tar.gz +1a697efd6563d8dfe167ac988b7929487c7517ca +39197 debianTag="debian/%e%v" patchedTag="patched/%e%v" upstreamTag="upstream/%e%u" diff -Nru dkimpy-0.6.1/dkim/crypto.py dkimpy-0.6.2/dkim/crypto.py --- dkimpy-0.6.1/dkim/crypto.py 2012-07-21 05:39:51.000000000 +0000 +++ dkimpy-0.6.2/dkim/crypto.py 2017-05-31 05:50:09.000000000 +0000 @@ -83,7 +83,7 @@ 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 @@ """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_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_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 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 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_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 -Nru dkimpy-0.6.1/dkim/__init__.py dkimpy-0.6.2/dkim/__init__.py --- dkimpy-0.6.1/dkim/__init__.py 2017-01-23 17:16:42.000000000 +0000 +++ dkimpy-0.6.2/dkim/__init__.py 2017-05-31 05:59:40.000000000 +0000 @@ -299,7 +299,7 @@ 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 @@ 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 @@ 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 @@ #: @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 @@ 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 @@ 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 @@ (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 @@ 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 @@ if logger is not None: logger.error("%s" % x) return CV_Fail, [], "%s" % x - Binary files /tmp/tmpGH2F0x/EY1b6C5nQo/dkimpy-0.6.1/dkim/.__init__.py.swo and /tmp/tmpGH2F0x/sniTXluBiC/dkimpy-0.6.2/dkim/.__init__.py.swo differ diff -Nru dkimpy-0.6.1/dkim/tests/test_dkim.py dkimpy-0.6.2/dkim/tests/test_dkim.py --- dkimpy-0.6.1/dkim/tests/test_dkim.py 2015-08-07 15:15:55.000000000 +0000 +++ dkimpy-0.6.2/dkim/tests/test_dkim.py 2017-05-30 16:07:39.000000000 +0000 @@ -16,6 +16,7 @@ # # Copyright (c) 2011 William Grant +import email import os.path import unittest import time @@ -87,6 +88,25 @@ 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 @@ # 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 @@ dv = dkim.DKIM(message) res = dv.verify(dnsfunc=self.dnsfunc) self.assertTrue(res) - + def test_extra_headers(self): # # extra headers above From caused failure diff -Nru dkimpy-0.6.1/dkim/util.py dkimpy-0.6.2/dkim/util.py --- dkimpy-0.6.1/dkim/util.py 2017-01-18 06:08:34.000000000 +0000 +++ dkimpy-0.6.2/dkim/util.py 2017-05-31 06:00:30.000000000 +0000 @@ -51,7 +51,7 @@ 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 -Nru dkimpy-0.6.1/PKG-INFO dkimpy-0.6.2/PKG-INFO --- dkimpy-0.6.1/PKG-INFO 2017-01-27 23:47:07.000000000 +0000 +++ dkimpy-0.6.2/PKG-INFO 2017-05-31 13:01:04.000000000 +0000 @@ -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 -Nru dkimpy-0.6.1/README dkimpy-0.6.2/README --- dkimpy-0.6.1/README 2017-01-27 23:44:49.000000000 +0000 +++ dkimpy-0.6.2/README 2017-05-31 12:59:03.000000000 +0000 @@ -11,14 +11,13 @@ 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 @@ 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 -Nru dkimpy-0.6.1/setup.py dkimpy-0.6.2/setup.py --- dkimpy-0.6.1/setup.py 2017-01-23 23:21:31.000000000 +0000 +++ dkimpy-0.6.2/setup.py 2017-01-27 23:53:06.000000000 +0000 @@ -24,7 +24,7 @@ from distutils.core import setup import os -version = "0.6.1" +version = "0.6.2" setup( name = "dkimpy",