+ GET_OPTION("dkim_sign_headers");
+ if ( dkim->dkim_sign_headers
+ && !(dkim_sign_headers_expanded = expand_string(dkim->dkim_sign_headers)))
+ { errwhen = US"dkim_sign_header"; goto expand_bad; }
+ /* else pass NULL, which means default header list */
+
+ /* Get private key to use. */
+
+ GET_OPTION("dkim_private_key");
+ if (!(dkim_private_key_expanded = expand_string(dkim->dkim_private_key)))
+ { errwhen = US"dkim_private_key"; goto expand_bad; }
+
+ if ( Ustrlen(dkim_private_key_expanded) == 0
+ || Ustrcmp(dkim_private_key_expanded, "0") == 0
+ || Ustrcmp(dkim_private_key_expanded, "false") == 0
+ )
+ continue; /* don't sign, but no error */
+
+ if ( dkim_private_key_expanded[0] == '/'
+ && !(dkim_private_key_expanded =
+ expand_file_big_buffer(dkim_private_key_expanded)))
+ goto bad;
+
+ GET_OPTION("dkim_hash");
+ if (!(dkim_hash_expanded = expand_string(dkim->dkim_hash)))
+ { errwhen = US"dkim_hash"; goto expand_bad; }
+
+ GET_OPTION("dkim_identity");
+ if (dkim->dkim_identity)
+ if (!(dkim_identity_expanded = expand_string(dkim->dkim_identity)))
+ { errwhen = US"dkim_identity"; goto expand_bad; }
+ else if (!*dkim_identity_expanded)
+ dkim_identity_expanded = NULL;
+
+ GET_OPTION("dkim_timestamps");
+ if (dkim->dkim_timestamps)
+ if (!(dkim_timestamps_expanded = expand_string(dkim->dkim_timestamps)))
+ { errwhen = US"dkim_timestamps"; goto expand_bad; }
+ else
+ {
+ tval = (unsigned long) time(NULL);
+ xval = strtoul(CCS dkim_timestamps_expanded, NULL, 10);
+ if (xval > 0)
+ xval += tval;
+ }
+
+ if (!(sig = pdkim_init_sign(&dkim_sign_ctx, dkim_signing_domain,
+ dkim_signing_selector,
+ dkim_private_key_expanded,
+ dkim_hash_expanded,
+ errstr
+ )))
+ goto bad;
+ dkim_private_key_expanded[0] = '\0';
+
+ pdkim_set_optional(sig,
+ CS dkim_sign_headers_expanded,
+ CS dkim_identity_expanded,
+ pdkim_canon,
+ pdkim_canon, -1, tval, xval);
+
+ if (!pdkim_set_sig_bodyhash(&dkim_sign_ctx, sig))
+ goto bad;
+
+ dkim_signing_record = string_append_listele(dkim_signing_record, ':', dkim_signing_domain);
+ dkim_signing_record = string_append_listele(dkim_signing_record, ':', dkim_signing_selector);
+
+ if (!dkim_sign_ctx.sig) /* link sig to context chain */
+ dkim_sign_ctx.sig = sig;
+ else