You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.6 KiB
PHP

<?php
namespace Cijber\OpenSSL;
use Cijber\OpenSSL;
use Cijber\OpenSSL\C\Memory;
use FFI;
use RuntimeException;
class PKCS7 extends OpenSSL\C\CBackedObjectWithOwner
{
const TYPE = "PKCS7*";
/**
* NID_pkcs7
*/
const NID = 20;
const NID_DATA = 21;
const NID_SIGNED = 22;
const NID_ENVELOPED = 23;
const NID_SIGNED_AND_ENVELOPED = 24;
const NID_DIGEST = 25;
const NID_ENCRYPTED = 26;
/**
* Verify with NID_ consts defined in Cijber\OpenSSL\PKCS7
* @return int
*/
public function getType(): int
{
return $this->ffi->OBJ_obj2nid($this->cObj->type);
}
public function asSigned(): PKCS7\Signed
{
$this->ensureNotFreed();
if ($this->getType() !== self::NID_SIGNED) {
throw new RuntimeException("This PKCS7 isn't of type signed");
}
return PKCS7\Signed::fromPKCS7($this, $this->ffi, $this->cObj->d->sign, $this->cObj);
}
/**
* Returns a DER representation of this PKCS7
*
* @return string
*/
public function toDER(): string
{
$this->ensureNotFreed();
// Create NULL uint8_t*
$buf = $this->ffi->new("uint8_t*");
// Get pointer from it (ptr being now uint8_t**)
$ptr = FFI::addr($buf);
// Give NULL pointer to OpenSSL and let it fill it up
$len = $this->ffi->i2d_PKCS7($this->cObj, $ptr);
if ($len < 0) {
throw new RuntimeException("Failed to create DER from PKCS7 object");
}
// Read string from pointer
$val = FFI::string($buf, $len);
// Free buffer via CRYPTO_free as OpenSSL malloc'd it
$this->ffi->CRYPTO_free($buf);
return $val;
}
/**
* @inheritDoc
*/
public function freeObject()
{
$this->ffi->PKCS7_free($this->cObj);
}
/**
* Create new PKCS7
*
* @return PKCS7
*/
public static function new(): PKCS7
{
$ffi = OpenSSL::getFFI();
$cObj = $ffi->PKCS7_new();
return new PKCS7($ffi, $cObj);
}
/**
* Load a PKCS7 object from DER
*
* @param string $der The string containing the DER
* @return PKCS7
*/
public static function loadFromDER(string $der): PKCS7
{
$ffi = OpenSSL::getFFI();
$derLen = strlen($der);
$mem = Memory::buffer($der);
$res = $ffi->d2i_PKCS7(null, $mem->pointer(), $derLen);
if ($res === null) {
throw new RuntimeException("Failed loading DER");
}
$mem->freed();
return static::cast($ffi, $res);
}
}