Skip to content

Commit

Permalink
Encrypted security event logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
paragonie-security committed Jan 20, 2018
1 parent c7a4b72 commit 0af1cb8
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 3 deletions.
62 changes: 60 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ to a Chronicle instance. This can be a public or private Chronicle.
composer require paragonie/monolog-quill
```

### Usage
## Usage

```php
<?php
Expand Down Expand Up @@ -49,7 +49,65 @@ $quill = (new Quill())

// Push the Handler to Monolog
$log = new Logger('security');
$log->pushHandler(new QuillHandler($quill, Logger::ALERT));
$handler = (new QuillHandler($quill, Logger::ALERT));
$log->pushHandler($handler);

// Now security events will be logged in your Chronicle
$log->alert(
'User bob logged in at ' .
((new DateTime())->format(\DateTime::ATOM))
);
```

### Encrypted Message Logging

Simply pass an instance of `SealingPublicKey` or `SharedEncryptionKey` to the
handler, via the `setEncryptionKey()` method, to encrypt log messages.

```php
$handler->setEncryptionKey(
new SealingPublicKey('/* Loaded from the filesystem or something. */')
);
```

#### Encrypted Message Logging - Complete Example

```php
<?php

use Monolog\Logger;
use ParagonIE\MonologQuill\QuillHandler;
use ParagonIE\Quill\Quill;
use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\Sapient\CryptographyKeys\{
SealingPublicKey,
SigningSecretKey,
SigningPublicKey
};

// Create a Quill for writing data to the Chronicle instance
$quill = (new Quill())
->setChronicleURL('https://chronicle-public-test.paragonie.com/chronicle')
->setServerPublicKey(
new SigningPublicKey(
Base64UrlSafe::decode('3BK4hOYTWJbLV5QdqS-DFKEYOMKd-G5M9BvfbqG1ICI=')
)
)
->setClientID('**Your Client ID provided by the Chronicle here**')
->setClientSecretKey(
new SigningSecretKey('/* Loaded from the filesystem or something. */')
);

// Push the Handler to Monolog
$log = new Logger('security');
$handler = (new QuillHandler($quill, Logger::ALERT));

// Set this to an instance of SealingPublicKey or SharedEncryptionKey:
$handler->setEncryptionKey(
new SealingPublicKey('/* Loaded from the filesystem or something. */')
);

$log->pushHandler($handler);

// Now security events will be logged in your Chronicle
$log->alert(
Expand Down
39 changes: 38 additions & 1 deletion src/QuillHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
use Monolog\Logger;
use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\Quill\Quill;
use ParagonIE\Sapient\CryptographyKey;
use ParagonIE\Sapient\CryptographyKeys\{
SealingPublicKey,
SharedEncryptionKey,
SigningPublicKey,
SigningSecretKey
};
Expand All @@ -19,6 +22,12 @@
*/
class QuillHandler extends AbstractProcessingHandler
{
/** @var SharedEncryptionKey|null $encryptionKey */
protected $encryptionKey = null;

/** @var SealingPublicKey|null $sealingKey */
protected $sealingKey = null;

/** @var Quill $quill */
protected $quill;

Expand Down Expand Up @@ -62,6 +71,28 @@ public function __construct(Quill $quill, int $level = Logger::DEBUG, bool $bubb
parent::__construct($level, $bubble);
}

/**
* @param CryptographyKey $encKey
* @return self
* @throws \TypeError
*/
public function setEncryptionKey(CryptographyKey $encKey = null): self
{
if (\is_null($encKey)) {
$this->sealingKey = null;
$this->encryptionKey = null;
} elseif ($encKey instanceof SealingPublicKey) {
$this->sealingKey = $encKey;
$this->encryptionKey = null;
} elseif ($encKey instanceof SharedEncryptionKey) {
$this->sealingKey = null;
$this->encryptionKey = $encKey;
} else {
throw new \TypeError('Invalid key type.');
}
return $this;
}

/**
* @param array $record
* @return void
Expand All @@ -84,6 +115,12 @@ protected function write(array $record)
$data = $ex->getMessage() . PHP_EOL . $ex->getTraceAsString();
}
}
$this->quill->blindWrite($data);
if (!\is_null($this->encryptionKey)) {
$this->quill->blindWriteEncrypted($data, $this->encryptionKey);
} elseif (!\is_null($this->sealingKey)) {
$this->quill->blindWriteSealed($data, $this->sealingKey);
} else {
$this->quill->blindWrite($data);
}
}
}

0 comments on commit 0af1cb8

Please sign in to comment.