Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. DkimSigner.php

function DkimSigner::sign

File

vendor/symfony/mime/Crypto/DkimSigner.php, line 61

Class

DkimSigner
@author Fabien Potencier <fabien@symfony.com>

Namespace

Symfony\Component\Mime\Crypto

Code

public function sign(Message $message, array $options = []) : Message {
    $options += $this->defaultOptions;
    if (!\in_array($options['algorithm'], [
        self::ALGO_SHA256,
        self::ALGO_ED25519,
    ], true)) {
        throw new InvalidArgumentException(\sprintf('Invalid DKIM signing algorithm "%s".', $options['algorithm']));
    }
    $headersToIgnore['return-path'] = true;
    $headersToIgnore['x-transport'] = true;
    foreach ($options['headers_to_ignore'] as $name) {
        $headersToIgnore[strtolower($name)] = true;
    }
    unset($headersToIgnore['from']);
    $signedHeaderNames = [];
    $headerCanonData = '';
    $headers = $message->getPreparedHeaders();
    foreach ($headers->getNames() as $name) {
        foreach ($headers->all($name) as $header) {
            if (isset($headersToIgnore[strtolower($header->getName())])) {
                continue;
            }
            if ('' !== $header->getBodyAsString()) {
                $headerCanonData .= $this->canonicalizeHeader($header->toString(), $options['header_canon']);
                $signedHeaderNames[] = $header->getName();
            }
        }
    }
    [
        $bodyHash,
        $bodyLength,
    ] = $this->hashBody($message->getBody(), $options['body_canon'], $options['body_max_length']);
    $params = [
        'v' => '1',
        'q' => 'dns/txt',
        'a' => $options['algorithm'],
        'bh' => base64_encode($bodyHash),
        'd' => $this->domainName,
        'h' => implode(': ', $signedHeaderNames),
        'i' => '@' . $this->domainName,
        's' => $this->selector,
        't' => time(),
        'c' => $options['header_canon'] . '/' . $options['body_canon'],
    ];
    if ($options['body_show_length']) {
        $params['l'] = $bodyLength;
    }
    if ($options['signature_expiration_delay']) {
        $params['x'] = $params['t'] + $options['signature_expiration_delay'];
    }
    $value = '';
    foreach ($params as $k => $v) {
        $value .= $k . '=' . $v . '; ';
    }
    $value = trim($value);
    $header = new UnstructuredHeader('DKIM-Signature', $value);
    $headerCanonData .= rtrim($this->canonicalizeHeader($header->toString() . "\r\n b=", $options['header_canon']));
    if (self::ALGO_SHA256 === $options['algorithm']) {
        if (!openssl_sign($headerCanonData, $signature, $this->key, \OPENSSL_ALGO_SHA256)) {
            throw new RuntimeException('Unable to sign DKIM hash: ' . openssl_error_string());
        }
    }
    else {
        throw new \RuntimeException(\sprintf('The "%s" DKIM signing algorithm is not supported yet.', self::ALGO_ED25519));
    }
    $header->setValue($value . ' b=' . trim(chunk_split(base64_encode($signature), 73, ' ')));
    $headers->add($header);
    return new Message($headers, $message->getBody());
}
RSS feed
Powered by Drupal