Revert a bunch of rsafp stuff now that DCRUP isn't going to do rsafp

This commit is contained in:
Scott Kitterman
2017-11-18 20:17:35 -05:00
parent 939c3f8bba
commit 01a2f77481
10 changed files with 32 additions and 163 deletions
+6 -13
View File
@@ -1,21 +1,14 @@
UNRELEASED Version 0.7.0 UNRELEASED Version 0.7.0
- Updated ARC implementation to support https://tools.ietf.org/html/ - Port dkimsign.py to use argparse; now gives standard usage message and
draft-ietf-dmarc-arc-protocol-08
- Authres module now required for ARC
- Ported dkimsign.py to use argparse; now gives standard usage message and
is more extensible is more extensible
- Added command line options to dkimsign.py to select header and body - Add command line options to dkimsign.py to select header and body
canonicalization algorithmns (LP: #1272724) canonicalization algorithmns (LP: #1272724)
- Added command line option to dkimsign.py to select signing algorithm - Add command line option to dkimsign.py to select signing algorithm
- For dknewkey.py made default to include h=sha256 in the DNS record to - For dknewkey.py make default to include h=sha256 in the DNS record to
exclude usage with sha1. Can be overriden. exclude usage with sha1. Can be overriden.
- Updated dknewkey.py to use argparse. Add --ktype option to specify - Update dknewkey.py to use argparse. Add --ktype option to specify
different key type options in anticipation of the DCRUP WG output. different key type options in anticipation of the DCRUP WG output.
- Added generation of rsafp DNS records per - Add generation of rsafp DNS records per draft-ietf-dcrup-dkim-crypto-02
draft-ietf-dcrup-dkim-crypto-02
- Added generation of rsafp DKIM signatures per
draft-ietf-dcrup-dkim-crypto-02
2017-05-30 Version 0.6.2 2017-05-30 Version 0.6.2
- Fixed problem with header folding that caused the first line to be - 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 folded too long (Updated test test_add_body_length since l= tag is no
-3
View File
@@ -20,7 +20,6 @@ REQUIREMENTS
and python 3.1 - 3.3. and python 3.1 - 3.3.
- dnspython or pydns. dnspython is preferred if both are present. - dnspython or pydns. dnspython is preferred if both are present.
- argparse. Standard library in python2.7 and later. - argparse. Standard library in python2.7 and later.
- authres. Needed only for ARC.
INSTALLATION INSTALLATION
@@ -96,8 +95,6 @@ Received Chain):
https://tools.ietf.org/html/draft-ietf-dmarc-arc-protocol-01 https://tools.ietf.org/html/draft-ietf-dmarc-arc-protocol-01
Updated to support -08 for 0.7.
This new functionality is marked experimental because the protocol is still This new functionality is marked experimental because the protocol is still
under development. There are no guarantees about API stability or under development. There are no guarantees about API stability or
compatibility. compatibility.
+23 -99
View File
@@ -38,13 +38,6 @@ import logging
import re import re
import time import time
# only needed for arc
try:
from authres import AuthenticationResultsHeader
except:
pass
from dkim.canonicalization import ( from dkim.canonicalization import (
CanonicalizationPolicy, CanonicalizationPolicy,
InvalidCanonicalizationPolicyError, InvalidCanonicalizationPolicyError,
@@ -56,7 +49,6 @@ from dkim.crypto import (
HASH_ALGORITHMS, HASH_ALGORITHMS,
parse_pem_private_key, parse_pem_private_key,
parse_public_key, parse_public_key,
get_rsa_pubkey,
RSASSA_PKCS1_v1_5_sign, RSASSA_PKCS1_v1_5_sign,
RSASSA_PKCS1_v1_5_verify, RSASSA_PKCS1_v1_5_verify,
UnparsableKeyError, UnparsableKeyError,
@@ -149,10 +141,6 @@ class ValidationError(DKIMException):
"""Validation error.""" """Validation error."""
pass pass
class AuthresNotFoundError(DKIMException):
""" Authres Package not installed, needed for ARC """
pass
def select_headers(headers, include_headers): def select_headers(headers, include_headers):
"""Select message header fields to be signed/verified. """Select message header fields to be signed/verified.
@@ -373,7 +361,7 @@ class DomainSigner(object):
#: @param logger: a logger to which debug info will be written (default None) #: @param logger: a logger to which debug info will be written (default None)
#: @param signature_algorithm: the signing algorithm to use when signing #: @param signature_algorithm: the signing algorithm to use when signing
def __init__(self,message=None,logger=None,signature_algorithm=b'rsa-sha256', def __init__(self,message=None,logger=None,signature_algorithm=b'rsa-sha256',
minkey=1024,ktype=b'rsa'): minkey=1024):
self.set_message(message) self.set_message(message)
if logger is None: if logger is None:
logger = get_default_logger() logger = get_default_logger()
@@ -394,8 +382,6 @@ class DomainSigner(object):
#: Minimum public key size. Shorter keys raise KeyFormatError. The #: Minimum public key size. Shorter keys raise KeyFormatError. The
#: default is 1024 #: default is 1024
self.minkey = minkey self.minkey = minkey
#: Key type to use. rsa, rsafp (DCRUP)
self.ktype = ktype
#: Header fields to protect from additions by default. #: Header fields to protect from additions by default.
#: #:
@@ -634,16 +620,12 @@ class DKIM(DomainSigner):
#: @raise DKIMException: when the message, include_headers, or key are badly #: @raise DKIMException: when the message, include_headers, or key are badly
#: formed. #: formed.
def sign(self, selector, domain, privkey, identity=None, def sign(self, selector, domain, privkey, identity=None,
canonicalize=(b'relaxed',b'simple'), include_headers=None, canonicalize=(b'relaxed',b'simple'), include_headers=None, length=False):
length=False):
try: try:
pk = parse_pem_private_key(privkey) pk = parse_pem_private_key(privkey)
except UnparsableKeyError as e: except UnparsableKeyError as e:
raise KeyFormatError(str(e)) raise KeyFormatError(str(e))
if self.ktype == b'rsafp':
pubkey = get_rsa_pubkey(privkey)
else:
pubkey = False
if identity is not None and not identity.endswith(domain): if identity is not None and not identity.endswith(domain):
raise ParameterError("identity must end with domain") raise ParameterError("identity must end with domain")
@@ -671,13 +653,10 @@ class DKIM(DomainSigner):
h = self.hasher() h = self.hasher()
h.update(body) h.update(body)
bodyhash = base64.b64encode(h.digest()) bodyhash = base64.b64encode(h.digest())
if self.ktype == b'rsafp':
atag = b'rsafp-sha256'
else:
atag = self.signature_algorithm
sigfields = [x for x in [ sigfields = [x for x in [
(b'v', b"1"), (b'v', b"1"),
(b'a', atag), (b'a', self.signature_algorithm),
(b'c', canon_policy.to_c_value()), (b'c', canon_policy.to_c_value()),
(b'd', domain), (b'd', domain),
(b'i', identity or b"@"+domain), (b'i', identity or b"@"+domain),
@@ -686,7 +665,6 @@ class DKIM(DomainSigner):
(b's', selector), (b's', selector),
(b't', str(int(time.time())).encode('ascii')), (b't', str(int(time.time())).encode('ascii')),
(b'h', b" : ".join(include_headers)), (b'h', b" : ".join(include_headers)),
pubkey and (b'k', pubkey),
(b'bh', bodyhash), (b'bh', bodyhash),
# Force b= to fold onto it's own line so that refolding after # Force b= to fold onto it's own line so that refolding after
# adding sig doesn't change whitespace for previous tags. # adding sig doesn't change whitespace for previous tags.
@@ -787,59 +765,27 @@ class ARC(DomainSigner):
#: @param selector: the DKIM selector value for the signature #: @param selector: the DKIM selector value for the signature
#: @param domain: the DKIM domain value for the signature #: @param domain: the DKIM domain value for the signature
#: @param privkey: a PKCS#1 private key in base64-encoded text form #: @param privkey: a PKCS#1 private key in base64-encoded text form
#: @param srv_id: an srv_id for identitfying AR headers to sign & extract cv from #: @param auth_results: RFC 7601 Authentication-Results header value for the message
#: @param chain_validation_status: CV_Pass, CV_Fail, CV_None
#: @param include_headers: a list of strings indicating which headers #: @param include_headers: a list of strings indicating which headers
#: are to be signed (default rfc4871 recommended headers) #: are to be signed (default rfc4871 recommended headers)
#: @return: list of ARC set header fields #: @return: list of ARC set header fields
#: @raise DKIMException: when the message, include_headers, or key are badly #: @raise DKIMException: when the message, include_headers, or key are badly
#: formed. #: formed.
def sign(self, selector, domain, privkey, srv_id, include_headers=None, def sign(self, selector, domain, privkey, auth_results, chain_validation_status,
timestamp=None, standardize=False): include_headers=None, timestamp=None, standardize=False):
# check if authres has been imported
try:
AuthenticationResultsHeader
except:
self.logger.debug("authres package not installed")
raise AuthresNotFoundError
try: try:
pk = parse_pem_private_key(privkey) pk = parse_pem_private_key(privkey)
except UnparsableKeyError as e: except UnparsableKeyError as e:
raise KeyFormatError(str(e)) raise KeyFormatError(str(e))
# extract, parse, filter & group AR headers
ar_headers = [res.strip() for [ar, res] in self.headers if ar == b'Authentication-Results']
grouped_headers = [(res, AuthenticationResultsHeader.parse('Authentication-Results: ' + res.decode('utf-8')))
for res in ar_headers]
auth_headers = [res for res in grouped_headers if res[1].authserv_id == srv_id.decode('utf-8')]
if len(auth_headers) == 0:
self.logger.debug("no AR headers found, chain terminated")
return b''
# consolidate headers
results_lists = [raw.replace(srv_id + b';', b'').strip() for (raw, parsed) in auth_headers]
results_lists = [tags.split(b';') for tags in results_lists]
results = [tag.strip() for sublist in results_lists for tag in sublist]
auth_results = srv_id + b'; ' + b';\r\n '.join(results)
# extract cv
parsed_auth_results = AuthenticationResultsHeader.parse('Authentication-Results: ' + auth_results.decode('utf-8'))
arc_results = [res for res in parsed_auth_results.results if res.method == 'arc']
if len(arc_results) == 0:
self.logger.debug("no AR arc stamps found, chain terminated")
return b''
elif len(arc_results) != 1:
self.logger.debug("multiple AR arc stamps found, failing chain")
chain_validation_status = CV_Fail
else:
chain_validation_status = arc_results[0].result.lower().encode('utf-8')
# Setup headers # Setup headers
if include_headers is None: if include_headers is None:
include_headers = self.default_sign_headers() include_headers = self.default_sign_headers()
if b'arc-authentication-results' not in include_headers:
include_headers.append(b'arc-authentication-results')
include_headers = tuple([x.lower() for x in include_headers]) include_headers = tuple([x.lower() for x in include_headers])
# record what verify should extract # record what verify should extract
@@ -865,10 +811,7 @@ class ARC(DomainSigner):
raise ParameterError("cv=none not allowed on instance %d" % instance) raise ParameterError("cv=none not allowed on instance %d" % instance)
new_arc_set = [] new_arc_set = []
if chain_validation_status != CV_Fail:
arc_headers = [y for x,y in arc_headers_w_instance] arc_headers = [y for x,y in arc_headers_w_instance]
else: # don't include previous sets for a failed/invalid chain
arc_headers = []
# Compute ARC-Authentication-Results # Compute ARC-Authentication-Results
aar_value = ("i=%d; " % instance).encode('utf-8') + auth_results aar_value = ("i=%d; " % instance).encode('utf-8') + auth_results
@@ -926,11 +869,6 @@ class ARC(DomainSigner):
as_include_headers = [x[0].lower() for x in arc_headers] as_include_headers = [x[0].lower() for x in arc_headers]
as_include_headers.reverse() as_include_headers.reverse()
# if our chain is failing or invalid, we only grab the most recent set
# reversing the order of the headers accomplishes this
if chain_validation_status == CV_Fail:
self.headers.reverse()
res = self.gen_header(as_fields, as_include_headers, canon_policy, res = self.gen_header(as_fields, as_include_headers, canon_policy,
b"ARC-Seal", pk, standardize) b"ARC-Seal", pk, standardize)
@@ -949,7 +887,7 @@ class ARC(DomainSigner):
#: @param dnsfunc: an optional function to lookup TXT resource records #: @param dnsfunc: an optional function to lookup TXT resource records
#: for a DNS domain. The default uses dnspython or pydns. #: for a DNS domain. The default uses dnspython or pydns.
#: @return: True if signature verifies or False otherwise #: @return: True if signature verifies or False otherwise
#: @return: three-tuple of (CV Result (CV_Pass, CV_Fail, CV_None or None, for a chain that has ended), list of #: @return: three-tuple of (CV Result (CV_Pass, CV_Fail or CV_None), list of
#: result dictionaries, result reason) #: result dictionaries, result reason)
#: @raise DKIMException: when the message, signature, or key are badly formed #: @raise DKIMException: when the message, signature, or key are badly formed
def verify(self,dnsfunc=get_txt): def verify(self,dnsfunc=get_txt):
@@ -969,10 +907,10 @@ class ARC(DomainSigner):
if not result_data[0]['ams-valid']: if not result_data[0]['ams-valid']:
return CV_Fail, result_data, "Most recent ARC-Message-Signature did not validate" return CV_Fail, result_data, "Most recent ARC-Message-Signature did not validate"
for result in result_data: for result in result_data:
if result['cv'] == CV_Fail: if not result['as-valid']:
return None, result_data, "ARC-Seal[%d] reported failure, the chain is terminated" % result['instance']
elif not result['as-valid']:
return CV_Fail, result_data, "ARC-Seal[%d] did not validate" % result['instance'] return CV_Fail, result_data, "ARC-Seal[%d] did not validate" % result['instance']
if result['cv'] == CV_Fail:
return CV_Fail, result_data, "ARC-Seal[%d] reported failure" % result['instance']
elif (result['instance'] == 1) and (result['cv'] != CV_None): elif (result['instance'] == 1) and (result['cv'] != CV_None):
return CV_Fail, result_data, "ARC-Seal[%d] reported invalid status %s" % (result['instance'], result['cv']) return CV_Fail, result_data, "ARC-Seal[%d] reported invalid status %s" % (result['instance'], result['cv'])
elif (result['instance'] != 1) and (result['cv'] == CV_None): elif (result['instance'] != 1) and (result['cv'] == CV_None):
@@ -1039,18 +977,7 @@ class ARC(DomainSigner):
raise ParameterError("The Arc-Message-Signature MUST NOT sign ARC-Seal") raise ParameterError("The Arc-Message-Signature MUST NOT sign ARC-Seal")
ams_header = (b'ARC-Message-Signature', b' ' + ams_value) ams_header = (b'ARC-Message-Signature', b' ' + ams_value)
ams_valid = self.verify_sig(sig, include_headers, ams_header, dnsfunc)
# we can't use the AMS provided above, as it's already been canonicalized relaxed
# for use in validating the AS. However the AMS is included in the AMS itself,
# and this can use simple canonicalization
raw_ams_header = [(x, y) for (x, y) in self.headers if x.lower() == b'arc-message-signature'][0]
try:
ams_valid = self.verify_sig(sig, include_headers, raw_ams_header, dnsfunc)
except DKIMException as e:
self.logger.error("%s" % e)
ams_valid = False
output['ams-valid'] = ams_valid output['ams-valid'] = ams_valid
self.logger.debug("ams valid: %r" % ams_valid) self.logger.debug("ams valid: %r" % ams_valid)
@@ -1071,11 +998,7 @@ class ARC(DomainSigner):
as_include_headers = [x[0].lower() for x in arc_headers] as_include_headers = [x[0].lower() for x in arc_headers]
as_include_headers.reverse() as_include_headers.reverse()
as_header = (b'ARC-Seal', b' ' + as_value) as_header = (b'ARC-Seal', b' ' + as_value)
try:
as_valid = self.verify_sig(sig, as_include_headers[:-1], as_header, dnsfunc) as_valid = self.verify_sig(sig, as_include_headers[:-1], as_header, dnsfunc)
except DKIMException as e:
self.logger.error("%s" % e)
as_valid = False
output['as-valid'] = as_valid output['as-valid'] = as_valid
self.logger.debug("as valid: %r" % as_valid) self.logger.debug("as valid: %r" % as_valid)
@@ -1122,7 +1045,8 @@ dkim_sign = sign
dkim_verify = verify dkim_verify = verify
def arc_sign(message, selector, domain, privkey, def arc_sign(message, selector, domain, privkey,
srv_id, signature_algorithm=b'rsa-sha256', auth_results, chain_validation_status,
signature_algorithm=b'rsa-sha256',
include_headers=None, timestamp=None, include_headers=None, timestamp=None,
logger=None, standardize=False): logger=None, standardize=False):
"""Sign an RFC822 message and return the ARC set header lines for the next instance """Sign an RFC822 message and return the ARC set header lines for the next instance
@@ -1130,19 +1054,19 @@ def arc_sign(message, selector, domain, privkey,
@param selector: the DKIM selector value for the signature @param selector: the DKIM selector value for the signature
@param domain: the DKIM domain value for the signature @param domain: the DKIM domain value for the signature
@param privkey: a PKCS#1 private key in base64-encoded text form @param privkey: a PKCS#1 private key in base64-encoded text form
@param srv_id: the authserv_id used to identify the ADMD's AR headers @param auth_results: the RFC 7601 authentication-results header field value for this instance
@param chain_validation_status: the validation status of the existing chain on the message (P (pass), F (fail)) or N (none) for no existing chain
@param signature_algorithm: the signing algorithm to use when signing @param signature_algorithm: the signing algorithm to use when signing
@param include_headers: a list of strings indicating which headers are to be signed (default all headers not listed as SHOULD NOT sign) @param include_headers: a list of strings indicating which headers are to be signed (default all headers not listed as SHOULD NOT sign)
@param logger: a logger to which debug info will be written (default None) @param logger: a logger to which debug info will be written (default None)
@return: A list containing the ARC set of header fields for the next instance @return: A list containing the ARC set of header fields for the next instance
@raise DKIMException: when the message, include_headers, or key are badly formed. @raise DKIMException: when the message, include_headers, or key are badly formed.
""" """
a = ARC(message,logger=logger,signature_algorithm=signature_algorithm) a = ARC(message,logger=logger,signature_algorithm=signature_algorithm)
if not include_headers: if not include_headers:
include_headers = a.default_sign_headers() include_headers = a.default_sign_headers()
return a.sign(selector, domain, privkey, srv_id, include_headers=include_headers, return a.sign(selector, domain, privkey, auth_results, chain_validation_status,
timestamp=timestamp, standardize=standardize) include_headers=include_headers, timestamp=timestamp, standardize=standardize)
def arc_verify(message, logger=None, dnsfunc=get_txt, minkey=1024): def arc_verify(message, logger=None, dnsfunc=get_txt, minkey=1024):
"""Verify the ARC chain on an RFC822 formatted message. """Verify the ARC chain on an RFC822 formatted message.
-10
View File
@@ -25,7 +25,6 @@ __all__ = [
'parse_pem_private_key', 'parse_pem_private_key',
'parse_private_key', 'parse_private_key',
'parse_public_key', 'parse_public_key',
'get_rsa_pubkey',
'RSASSA_PKCS1_v1_5_sign', 'RSASSA_PKCS1_v1_5_sign',
'RSASSA_PKCS1_v1_5_verify', 'RSASSA_PKCS1_v1_5_verify',
'UnparsableKeyError', 'UnparsableKeyError',
@@ -34,7 +33,6 @@ __all__ = [
import base64 import base64
import hashlib import hashlib
import re import re
import rsa
from dkim.asn1 import ( from dkim.asn1 import (
ASN1FormatError, ASN1FormatError,
@@ -235,14 +233,6 @@ def rsa_decrypt(message, pk, mlen):
return int2str(m2 + h * pk['prime2'], mlen) return int2str(m2 + h * pk['prime2'], mlen)
def get_rsa_pubkey(privkey):
"""Extract RSA public key from PEM encoded RSA private key for use with
rsafp. Returns base64 encoded public key suitable for use in DKIM key
records. Using python-rsa instead of making a stack of custom code.
@since: 0.7"""
pkobj = rsa.PrivateKey.load_pkcs1(privkey, 'PEM')
pubobj = rsa.key.PublicKey(pkobj.n, pkobj.e)
return(base64.b64encode(rsa.PublicKey.save_pkcs1(pubobj, 'DER')))
def rsa_encrypt(message, pk, mlen): def rsa_encrypt(message, pk, mlen):
"""Perform RSA encryption/verification """Perform RSA encryption/verification
-2
View File
@@ -28,7 +28,6 @@ def test_suite():
test_canonicalization, test_canonicalization,
test_crypto, test_crypto,
test_dkim, test_dkim,
test_rsafp,
test_util, test_util,
test_arc, test_arc,
test_dnsplug, test_dnsplug,
@@ -37,7 +36,6 @@ def test_suite():
test_canonicalization, test_canonicalization,
test_crypto, test_crypto,
test_dkim, test_dkim,
test_rsafp,
test_util, test_util,
test_arc, test_arc,
test_dnsplug, test_dnsplug,
-1
View File
@@ -1 +0,0 @@
k=rsafp; p=VO1v0Ybphw9AlrLvHB2ly/x6RD/1zJxEhYeWT/v/RtY=
-27
View File
@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA0EGLyxVqSMvpQ/THu4XH+0sbqQrnGRu36/TBcsJc7p5vGKIY
f7lfAiaxceGGVX1NzBoE8SEqmLlNuRtdHSsnItC82m5hGDhTec8ZcGonfnOCPJvd
Dou8mDXhtX9knES4PC/Uup3HL84RnsXZ0GWpUtB+fIsHlZryFjsTJtOZVdJSH5H5
B0arJCitLVJqPqF5bluIVuXmwXD2Wi0hQkpmSm+SJJQ1efTkpK2UYkJvu8cMF7aA
7Lgxzimatqg4oDg9ED5VCHFz82wacjNrnQRnezeOcWF8q76dfCDo5MLUO+CWChFC
H897B6kjMmCo3IavLTHB8Dc7q70I8lxn2qAZzwIDAQABAoIBAQCU+R5oExSpqHxg
KV0rbqLEx1CtFuiD1Ik32Cj9z72s0FcGlwXRcChfoJA0t7BhvTYGt+IrH5+aCoxn
ywRL1k+znwBJfMYmDjzgmN5IxRclZLmYY6K5QgqSE5E3RT8SbjIgk9KoAC+5qb5/
BmcupVp/rDefHdE6GtHsRywHDTzV30f8zXb/51w30FkcSQS85v8W4VbyqpGcAgq1
ah1gEuSd7HtxQ4HWyvFiMdw+0bBh8gt14Dh3nq8i6tDhlPtykbM4etm16fcpl5cz
DOg5srIOKxW4vGOng68v6KQ/gz8/BQMAPbZHgFd5l2grejC9p27hwTYer909AfEO
EUcn5oJhAoGBAPVoqvcqA4AL3G46SrYeAnXz/bpaPiBhKat1YgnPQc+5cuGauJIN
YtiCv5xza1u8Gc5rRfEn/41mSpDAXcix0d95qpUAToNVRJUA23e28EoKGL8rWaXF
lc2IecGNI7HF7XL0V+BF59dAPH4q44mKval6U/wTo0hDAFfBnRy0V03RAoGBANk+
Z9G7dYaQpw/nCxVouCeGOX4LECt4m4Y+LIhFPqI8mnTM8S97dnySW3OpafwF6RIk
UDMzXSJc6BPOMEk9WVI+1ztKXssjbvVa3fSHZEBMP9d1xFJw4/SRSp3uFjGzLa4u
pea8DFRz5jBR2uyGh0+/1E9v+hem7WD6pwJGwrWfAoGAVeiEIO4GN6bvTW7+hG5Q
8jWtlrTMls0spyb6YPC62xrSSoO9JPOmrKBorz4AUSax6f7Hhzo3TaqHY9DTg9Qr
4g1XV725vmP1FCwup+PUjjamnxVv1oYqgL7L0KO14R+mld1PfeU62bFU+93LtXRq
HJAEInRFbqB12EKg21GOVmECgYA6Lox/j0UalQMpLye4xCMN8tTS/QOHoPWGLoCe
vmzX5oM3ZOvzW42QL2Jux6Cq7qpNQYx5Kfh3i4pcQ4yLEPMrI8lhB7n7jbHZ5Ewt
gVVIIyO2AMRjj/h9N6xUP7+R7/r7+2JTOWnT9HZh2opXbnAu26Fw5PyF+R76Kicw
ZOMg4QKBgQDMAJ9nENCiZw7CkYRm+z5UoMeSR3jwEPj1gK3KKhIYWeOw99i2XmBt
1aN0UgAeEidleguqeZWxVXJkdVqvxfAPqpPfhGneN5GgEh2gOfFTDrvHhqoMblsw
uuNlIixfy4w1ENApV2n7qcBzptMHV2uPDUHCctAZ9+ACg7nkiJEaCw==
-----END RSA PRIVATE KEY-----
-1
View File
@@ -1 +0,0 @@
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0EGLyxVqSMvpQ/THu4XH+0sbqQrnGRu36/TBcsJc7p5vGKIYf7lfAiaxceGGVX1NzBoE8SEqmLlNuRtdHSsnItC82m5hGDhTec8ZcGonfnOCPJvdDou8mDXhtX9knES4PC/Uup3HL84RnsXZ0GWpUtB+fIsHlZryFjsTJtOZVdJSH5H5B0arJCitLVJqPqF5bluIVuXmwXD2Wi0hQkpmSm+SJJQ1efTkpK2UYkJvu8cMF7aA7Lgxzimatqg4oDg9ED5VCHFz82wacjNrnQRnezeOcWF8q76dfCDo5MLUO+CWChFCH897B6kjMmCo3IavLTHB8Dc7q70I8lxn2qAZzwIDAQAB
+1 -5
View File
@@ -47,9 +47,6 @@ parser.add_argument('--bcanon', choices=['simple', 'relaxed'],
parser.add_argument('--signalg', choices=['rsa-sha256', 'rsa-sha1'], parser.add_argument('--signalg', choices=['rsa-sha256', 'rsa-sha1'],
default='rsa-sha256', default='rsa-sha256',
help='Signature algorithm: default=rsa-sha256') help='Signature algorithm: default=rsa-sha256')
parser.add_argument('--ktype', choices=['rsa', 'rsafp'],
default='rsa',
help='DKIM key type: Default is rsa')
parser.add_argument('--identity', help='Optional value for i= tag.') parser.add_argument('--identity', help='Optional value for i= tag.')
args=parser.parse_args(arguments) args=parser.parse_args(arguments)
include_headers = None include_headers = None
@@ -64,7 +61,6 @@ if sys.version_info[0] >= 3:
args.hcanon = bytes(args.hcanon, encoding='UTF-8') args.hcanon = bytes(args.hcanon, encoding='UTF-8')
args.bcanon = bytes(args.bcanon, encoding='UTF-8') args.bcanon = bytes(args.bcanon, encoding='UTF-8')
args.signalg = bytes(args.signalg, encoding='UTF-8') args.signalg = bytes(args.signalg, encoding='UTF-8')
args.ktype = bytes(args.ktype, encoding='UTF-8')
# Make sys.stdin and stdout binary streams. # Make sys.stdin and stdout binary streams.
sys.stdin = sys.stdin.detach() sys.stdin = sys.stdin.detach()
sys.stdout = sys.stdout.detach() sys.stdout = sys.stdout.detach()
@@ -73,7 +69,7 @@ canonicalize = (args.hcanon, args.bcanon)
message = sys.stdin.read() message = sys.stdin.read()
try: try:
d = dkim.DKIM(message,logger=logger, d = dkim.DKIM(message,logger=logger,
signature_algorithm=args.signalg, ktype=args.ktype) signature_algorithm=args.signalg)
sig = d.sign(args.selector, args.domain, open( sig = d.sign(args.selector, args.domain, open(
args.privatekeyfile, "rb").read(), identity = args.identity, args.privatekeyfile, "rb").read(), identity = args.identity,
canonicalize=canonicalize, include_headers=include_headers, canonicalize=canonicalize, include_headers=include_headers,
Executable → Regular
View File