Compare commits
No commits in common. "c0e61c21f07cacf0cacfd215160031e5153c25b4" and "fb1ec4e0591693a2aa65bf4f436ec8897aa8d3ae" have entirely different histories.
c0e61c21f0
...
fb1ec4e059
5 changed files with 17 additions and 107 deletions
|
@ -1,5 +1,3 @@
|
||||||
void CRYPTO_free(void *addr);
|
|
||||||
|
|
||||||
typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
|
typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
|
||||||
struct crypto_ex_data_st {
|
struct crypto_ex_data_st {
|
||||||
struct stack_st_void *sk;
|
struct stack_st_void *sk;
|
||||||
|
|
|
@ -6,4 +6,4 @@ void OPENSSL_add_all_algorithms_conf(void);
|
||||||
void OPENSSL_add_all_algorithms_noconf(void);
|
void OPENSSL_add_all_algorithms_noconf(void);
|
||||||
|
|
||||||
void ERR_load_crypto_strings(void);
|
void ERR_load_crypto_strings(void);
|
||||||
void ERR_free_strings(void);
|
void ERR_free_strings(void);
|
||||||
|
|
|
@ -196,60 +196,33 @@ class BIO extends CBackedObjectWithOwner
|
||||||
const FLAG_RWS = self::FLAG_READ | self::FLAG_WRITE | self::FLAG_IO_SPECIAL;
|
const FLAG_RWS = self::FLAG_READ | self::FLAG_WRITE | self::FLAG_IO_SPECIAL;
|
||||||
const FLAG_SHOULD_RETRY = 0x08;
|
const FLAG_SHOULD_RETRY = 0x08;
|
||||||
|
|
||||||
/**
|
|
||||||
* Create new memory based BIO
|
public static function new()
|
||||||
*
|
|
||||||
* @return BIO
|
|
||||||
*/
|
|
||||||
public static function new(): BIO
|
|
||||||
{
|
{
|
||||||
$ffi = OpenSSL::getFFI();
|
$ffi = OpenSSL::getFFI();
|
||||||
$bio = $ffi->BIO_new($ffi->BIO_s_mem());
|
$bio = $ffi->BIO_new($ffi->BIO_s_mem());
|
||||||
return new BIO($ffi, $bio);
|
return new BIO($ffi, $bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function buffer(string $data)
|
||||||
* Create new memory based BIO pre-filled with data
|
|
||||||
*
|
|
||||||
* @param string $data
|
|
||||||
* @return BIO
|
|
||||||
*/
|
|
||||||
public static function buffer(string $data): BIO
|
|
||||||
{
|
{
|
||||||
$ffi = OpenSSL::getFFI();
|
$ffi = OpenSSL::getFFI();
|
||||||
$bio = $ffi->BIO_new_mem_buf($data, strlen($data));
|
$bio = $ffi->BIO_new_mem_buf($data, strlen($data));
|
||||||
return new BIO($ffi, $bio);
|
return new BIO($ffi, $bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function open($fileName, $flags)
|
||||||
* Create new file BIO with given mode
|
|
||||||
*
|
|
||||||
* @param string $fileName which file to open
|
|
||||||
* @param string $mode mode to open file with see fopen(3)
|
|
||||||
* @return BIO
|
|
||||||
* @see fopen
|
|
||||||
*/
|
|
||||||
public static function open(string $fileName, string $mode): BIO
|
|
||||||
{
|
{
|
||||||
$ffi = OpenSSL::getFFI();
|
$ffi = OpenSSL::getFFI();
|
||||||
$bio = $ffi->BIO_new_file($fileName, $mode);
|
$bio = $ffi->BIO_new_file($fileName, $flags);
|
||||||
return new BIO($ffi, $bio);
|
return new BIO($ffi, $bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
protected function freeObject()
|
protected function freeObject()
|
||||||
{
|
{
|
||||||
$this->ffi->BIO_free($this->cObj);
|
$this->ffi->BIO_free($this->cObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Write given data to BIO, returns amount of bytes written
|
|
||||||
*
|
|
||||||
* @param string $data
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
function write(string $data): int
|
function write(string $data): int
|
||||||
{
|
{
|
||||||
$len = $this->ffi->BIO_write($this->cObj, $data, strlen($data));
|
$len = $this->ffi->BIO_write($this->cObj, $data, strlen($data));
|
||||||
|
@ -268,22 +241,11 @@ class BIO extends CBackedObjectWithOwner
|
||||||
return $len;
|
return $len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get type of BIO, indicating if this is e.g. a file see BIO::TYPE_* constants
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
function getType(): int
|
function getType(): int
|
||||||
{
|
{
|
||||||
return $this->ffi->BIO_method_type($this->cObj);
|
return $this->ffi->BIO_method_type($this->cObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from BIO
|
|
||||||
*
|
|
||||||
* @param int $chunkSize max amount of bytes to read in this operation
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function read(int $chunkSize = 4096): string
|
function read(int $chunkSize = 4096): string
|
||||||
{
|
{
|
||||||
$data = OpenSSL\C\Memory::new($chunkSize);
|
$data = OpenSSL\C\Memory::new($chunkSize);
|
||||||
|
@ -303,11 +265,6 @@ class BIO extends CBackedObjectWithOwner
|
||||||
return $data->string($len);
|
return $data->string($len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get location in file pointer, this only works with file BIO's
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
function tell()
|
function tell()
|
||||||
{
|
{
|
||||||
if (($this->getType() & self::TYPE_FILE) !== self::TYPE_FILE) {
|
if (($this->getType() & self::TYPE_FILE) !== self::TYPE_FILE) {
|
||||||
|
@ -323,10 +280,7 @@ class BIO extends CBackedObjectWithOwner
|
||||||
return $pos;
|
return $pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function reset()
|
||||||
* Reset position in BIO
|
|
||||||
*/
|
|
||||||
function reset(): void
|
|
||||||
{
|
{
|
||||||
$res = (int)$this->ctrl(self::CTRL_RESET, 0, null);
|
$res = (int)$this->ctrl(self::CTRL_RESET, 0, null);
|
||||||
|
|
||||||
|
@ -341,11 +295,6 @@ class BIO extends CBackedObjectWithOwner
|
||||||
throw new RuntimeException("Failed to reset BIO");
|
throw new RuntimeException("Failed to reset BIO");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Seek in BIO, only works on file BIO's
|
|
||||||
*
|
|
||||||
* @param int $offset
|
|
||||||
*/
|
|
||||||
function seek(int $offset)
|
function seek(int $offset)
|
||||||
{
|
{
|
||||||
if (($this->getType() & self::TYPE_FILE) !== self::TYPE_FILE) {
|
if (($this->getType() & self::TYPE_FILE) !== self::TYPE_FILE) {
|
||||||
|
@ -359,25 +308,12 @@ class BIO extends CBackedObjectWithOwner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* returns true if we're at EOF of this BIO
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
function eof(): bool
|
function eof(): bool
|
||||||
{
|
{
|
||||||
return (int)$this->ctrl(self::CTRL_EOF, 0, null) === 1;
|
return (int)$this->ctrl(self::CTRL_EOF, 0, null) === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function ctrl($prop, ?int $larg, $parg)
|
||||||
* Send control command to BIO
|
|
||||||
*
|
|
||||||
* @param int $prop
|
|
||||||
* @param int $larg
|
|
||||||
* @param mixed $parg
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
function ctrl(int $prop, int $larg = 0, $parg = null)
|
|
||||||
{
|
{
|
||||||
return $this->ffi->BIO_ctrl($this->cObj, $prop, $larg, $parg);
|
return $this->ffi->BIO_ctrl($this->cObj, $prop, $larg, $parg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,20 +36,8 @@ class PKCS7 extends OpenSSL\C\CBackedObjectWithOwner
|
||||||
if (!in_array($type, [PKCS7::NID_DIGEST, self::NID_SIGNED, self::NID_SIGNED_AND_ENVELOPED])) {
|
if (!in_array($type, [PKCS7::NID_DIGEST, self::NID_SIGNED, self::NID_SIGNED_AND_ENVELOPED])) {
|
||||||
throw new \RuntimeException("Can only verify signed or digested data");
|
throw new \RuntimeException("Can only verify signed or digested data");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function toDER(): string
|
|
||||||
{
|
|
||||||
$buf = $this->ffi->new("uint8_t*");
|
|
||||||
$ptr = FFI::addr($buf);
|
|
||||||
$len = $this->ffi->i2d_PKCS7($this->cObj, $ptr);
|
|
||||||
if ($len < 0) {
|
|
||||||
throw new \RuntimeException("Failed to create DER from PKCS7 object");
|
|
||||||
}
|
|
||||||
|
|
||||||
$val = FFI::string($buf, $len);
|
|
||||||
$this->ffi->CRYPTO_free($buf);
|
|
||||||
return $val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function freeObject()
|
public function freeObject()
|
||||||
|
@ -66,16 +54,16 @@ class PKCS7 extends OpenSSL\C\CBackedObjectWithOwner
|
||||||
|
|
||||||
public static function loadFromDER(string $der): PKCS7
|
public static function loadFromDER(string $der): PKCS7
|
||||||
{
|
{
|
||||||
$ffi = OpenSSL::getFFI();
|
$pkcs = static::new();
|
||||||
|
$pkcs->loadDER($der);
|
||||||
|
return $pkcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadDER(string $der)
|
||||||
|
{
|
||||||
$derLen = strlen($der);
|
$derLen = strlen($der);
|
||||||
$mem = Memory::buffer($der);
|
$mem = Memory::buffer($der);
|
||||||
$res = $ffi->d2i_PKCS7(null, $mem->pointer(), $derLen);
|
$this->ffi->d2i_PKCS7(FFI::addr($this->cObj), $mem->pointer(), $derLen);
|
||||||
|
|
||||||
if ($res === null) {
|
|
||||||
throw new \RuntimeException("Failed loading DER");
|
|
||||||
}
|
|
||||||
|
|
||||||
$mem->freed();
|
$mem->freed();
|
||||||
return new static($ffi, $res);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@ namespace Cijber\OpenSSL\Tests;
|
||||||
|
|
||||||
use Cijber\OpenSSL\PKCS7;
|
use Cijber\OpenSSL\PKCS7;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
class PKCS7Test extends TestCase
|
class PKCS7Test extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -15,20 +14,9 @@ class PKCS7Test extends TestCase
|
||||||
unset($pkcs7);
|
unset($pkcs7);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadDER()
|
public function testLoadDER() {
|
||||||
{
|
|
||||||
$der = file_get_contents(__DIR__ . "/data/pkcs7/1.RSA");
|
$der = file_get_contents(__DIR__ . "/data/pkcs7/1.RSA");
|
||||||
$pkcs7 = PKCS7::loadFromDER($der);
|
$pkcs7 = PKCS7::loadFromDER($der);
|
||||||
$newDer = $pkcs7->toDER();
|
|
||||||
$this->assertEquals($der, $newDer);
|
|
||||||
$this->assertEquals(PKCS7::NID_SIGNED, $pkcs7->getType());
|
$this->assertEquals(PKCS7::NID_SIGNED, $pkcs7->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadingGarbageDER()
|
|
||||||
{
|
|
||||||
$this->expectException(RuntimeException::class);
|
|
||||||
$this->expectExceptionMessage("Failed loading DER");
|
|
||||||
|
|
||||||
PKCS7::loadFromDER("blaat");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue