Compare commits
3 commits
cf83bc8c5d
...
eeece17518
Author | SHA1 | Date | |
---|---|---|---|
eeece17518 | |||
2f9c850c52 | |||
31a5b24ded |
17 changed files with 210 additions and 35 deletions
|
@ -4,7 +4,8 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"require": {
|
"require": {
|
||||||
"ext-FFI": "*",
|
"ext-FFI": "*",
|
||||||
"php": "^7.4"
|
"php": "^7.4",
|
||||||
|
"ext-openssl": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^0.11.19",
|
"phpstan/phpstan": "^0.11.19",
|
||||||
|
|
|
@ -58,11 +58,8 @@ typedef struct pkcs7_signedandenveloped_st {
|
||||||
ASN1_INTEGER *version;
|
ASN1_INTEGER *version;
|
||||||
|
|
||||||
struct stack_st_X509_ALGOR *md_algs;
|
struct stack_st_X509_ALGOR *md_algs;
|
||||||
|
|
||||||
struct stack_st_X509 *cert;
|
struct stack_st_X509 *cert;
|
||||||
|
|
||||||
struct stack_st_X509_CRL *crl;
|
struct stack_st_X509_CRL *crl;
|
||||||
|
|
||||||
struct stack_st_PKCS7_SIGNER_INFO *signer_info;
|
struct stack_st_PKCS7_SIGNER_INFO *signer_info;
|
||||||
|
|
||||||
PKCS7_ENC_CONTENT *enc_data;
|
PKCS7_ENC_CONTENT *enc_data;
|
||||||
|
|
|
@ -234,8 +234,56 @@ struct stack_st_X509_CRL {
|
||||||
_STACK stack;
|
_STACK stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct x509_lookup_st X509_LOOKUP;
|
||||||
|
|
||||||
|
typedef struct x509_object_st
|
||||||
|
{
|
||||||
|
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
char *ptr;
|
||||||
|
X509 *x509;
|
||||||
|
X509_CRL *crl;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
} data;
|
||||||
|
} X509_OBJECT;
|
||||||
|
|
||||||
|
struct stack_st_X509_LOOKUP { _STACK stack; };
|
||||||
|
struct stack_st_X509_OBJECT { _STACK stack; };
|
||||||
|
|
||||||
|
typedef struct x509_lookup_method_st {
|
||||||
|
const char *name;
|
||||||
|
int (*new_item)(X509_LOOKUP *ctx);
|
||||||
|
void (*free)(X509_LOOKUP *ctx);
|
||||||
|
int (*init)(X509_LOOKUP *ctx);
|
||||||
|
int (*shutdown)(X509_LOOKUP *ctx);
|
||||||
|
int (*ctrl)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
|
||||||
|
char **ret);
|
||||||
|
int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name,
|
||||||
|
X509_OBJECT *ret);
|
||||||
|
int (*get_by_issuer_serial)(X509_LOOKUP *ctx, int type, X509_NAME *name,
|
||||||
|
ASN1_INTEGER *serial, X509_OBJECT *ret);
|
||||||
|
int (*get_by_fingerprint)(X509_LOOKUP *ctx, int type,
|
||||||
|
const unsigned char *bytes, int len,
|
||||||
|
X509_OBJECT *ret);
|
||||||
|
int (*get_by_alias)(X509_LOOKUP *ctx, int type, const char *str, int len,
|
||||||
|
X509_OBJECT *ret);
|
||||||
|
} X509_LOOKUP_METHOD;
|
||||||
|
|
||||||
X509 *X509_new(void);
|
X509 *X509_new(void);
|
||||||
|
X509 *X509_dup(X509 *x509);
|
||||||
void X509_free(X509 *a);
|
void X509_free(X509 *a);
|
||||||
|
|
||||||
X509_STORE *X509_STORE_new(void);
|
X509_STORE *X509_STORE_new(void);
|
||||||
void X509_STORE_free(X509_STORE *v);
|
void X509_STORE_free(X509_STORE *v);
|
||||||
|
|
||||||
|
X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
|
||||||
|
|
||||||
|
X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
|
||||||
|
X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
|
||||||
|
X509_LOOKUP_METHOD *X509_LOOKUP_mem(void);
|
||||||
|
|
||||||
|
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
|
||||||
|
|
||||||
|
int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
|
||||||
|
long argl, char **ret);
|
|
@ -5,6 +5,7 @@ namespace Cijber;
|
||||||
|
|
||||||
use Cijber\OpenSSL\FFIWrapper;
|
use Cijber\OpenSSL\FFIWrapper;
|
||||||
use Cijber\OpenSSL\Instance;
|
use Cijber\OpenSSL\Instance;
|
||||||
|
use Cijber\OpenSSL\X509Store;
|
||||||
use FFI;
|
use FFI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,7 +57,8 @@ class OpenSSL
|
||||||
$ffi = static::getFFI();
|
$ffi = static::getFFI();
|
||||||
$errs = [];
|
$errs = [];
|
||||||
while (0 !== ($code = $ffi->ERR_get_error())) {
|
while (0 !== ($code = $ffi->ERR_get_error())) {
|
||||||
$errs[] = FFI::string($ffi->ERR_error_string($code, null));
|
$ptr = $ffi->ERR_error_string($code, null);
|
||||||
|
$errs[] = FFI::string($ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $errs;
|
return $errs;
|
||||||
|
@ -66,4 +68,15 @@ class OpenSSL
|
||||||
{
|
{
|
||||||
return FFI::cast("long long", $data)->cdata;
|
return FFI::cast("long long", $data)->cdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static $caStore = null;
|
||||||
|
|
||||||
|
public static function CAStore()
|
||||||
|
{
|
||||||
|
if (static::$caStore === null) {
|
||||||
|
static::$caStore = X509Store::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$caStore;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,4 +94,9 @@ class CBackedObject
|
||||||
{
|
{
|
||||||
$this->managed = true;
|
$this->managed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCData(): CData
|
||||||
|
{
|
||||||
|
return $this->cObj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
|
|
||||||
namespace Cijber\OpenSSL\C;
|
namespace Cijber\OpenSSL\C;
|
||||||
|
|
||||||
|
use Cijber\OpenSSL;
|
||||||
use Cijber\OpenSSL\FFIWrapper;
|
use Cijber\OpenSSL\FFIWrapper;
|
||||||
use FFI;
|
use FFI;
|
||||||
use FFI\CData;
|
use FFI\CData;
|
||||||
|
|
||||||
class CBackedObjectWithOwner extends CBackedObject
|
class CBackedObjectWithOwner extends CBackedObject
|
||||||
{
|
{
|
||||||
static private array $known = [];
|
private static array $known = [];
|
||||||
private int $address = -1;
|
private int $address = -1;
|
||||||
|
|
||||||
protected FFI $ffi;
|
protected FFI $ffi;
|
||||||
|
@ -43,7 +44,7 @@ class CBackedObjectWithOwner extends CBackedObject
|
||||||
* Cast first, so it acts like a pointer
|
* Cast first, so it acts like a pointer
|
||||||
*/
|
*/
|
||||||
$casted = $ffi->cast(static::TYPE, $cData);
|
$casted = $ffi->cast(static::TYPE, $cData);
|
||||||
$address = FFI::cast("long long", $casted)->cdata;
|
$address = OpenSSL::addressOf($casted);
|
||||||
if (array_key_exists($address, static::$known)) {
|
if (array_key_exists($address, static::$known)) {
|
||||||
return static::$known[$address];
|
return static::$known[$address];
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ class PKCS7 extends OpenSSL\C\CBackedObjectWithOwner
|
||||||
return $this->ffi->OBJ_obj2nid($this->cObj->type);
|
return $this->ffi->OBJ_obj2nid($this->cObj->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toSigned(): PKCS7\Signed
|
public function asSigned(): PKCS7\Signed
|
||||||
{
|
{
|
||||||
$this->ensureNotFreed();
|
$this->ensureNotFreed();
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class PKCS7 extends OpenSSL\C\CBackedObjectWithOwner
|
||||||
throw new RuntimeException("This PKCS7 isn't of type signed");
|
throw new RuntimeException("This PKCS7 isn't of type signed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PKCS7\Signed($this);
|
return PKCS7\Signed::fromPKCS7($this, $this->ffi, $this->cObj->d->sign, $this->cObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,10 +4,28 @@
|
||||||
namespace Cijber\OpenSSL\PKCS7;
|
namespace Cijber\OpenSSL\PKCS7;
|
||||||
|
|
||||||
use Cijber\OpenSSL\PKCS7;
|
use Cijber\OpenSSL\PKCS7;
|
||||||
|
use FFI;
|
||||||
|
use FFI\CData;
|
||||||
|
|
||||||
trait Helpers
|
trait Helpers
|
||||||
{
|
{
|
||||||
protected PKCS7 $pkcs7;
|
protected PKCS7 $pkcs7;
|
||||||
|
protected CData $data;
|
||||||
|
protected CData $parent;
|
||||||
|
protected FFI $ffi;
|
||||||
|
|
||||||
|
public function __construct(PKCS7 $pkcs7, FFI $ffi, CData $data, CData $parent)
|
||||||
|
{
|
||||||
|
$this->pkcs7 = $pkcs7;
|
||||||
|
$this->ffi = $ffi;
|
||||||
|
$this->data = $data;
|
||||||
|
$this->parent = $parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromPKCS7(PKCS7 $param, FFI $ffi, CData $data, CData $parent)
|
||||||
|
{
|
||||||
|
return new static($param, $ffi, $data, $parent);
|
||||||
|
}
|
||||||
|
|
||||||
public function toDER(): string
|
public function toDER(): string
|
||||||
{
|
{
|
||||||
|
@ -21,9 +39,4 @@ trait Helpers
|
||||||
{
|
{
|
||||||
return $this->pkcs7;
|
return $this->pkcs7;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct(PKCS7 $pkcs7)
|
|
||||||
{
|
|
||||||
$this->pkcs7 = $pkcs7;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,31 @@
|
||||||
|
|
||||||
namespace Cijber\OpenSSL\PKCS7;
|
namespace Cijber\OpenSSL\PKCS7;
|
||||||
|
|
||||||
|
use Cijber\OpenSSL;
|
||||||
|
use Cijber\OpenSSL\BIO;
|
||||||
|
use Cijber\OpenSSL\Stack\X509Stack;
|
||||||
|
use Cijber\OpenSSL\X509Store;
|
||||||
|
|
||||||
class Signed
|
class Signed
|
||||||
{
|
{
|
||||||
use Helpers;
|
use Helpers;
|
||||||
|
|
||||||
public function getSigners()
|
|
||||||
|
public function getCerts(): X509Stack
|
||||||
{
|
{
|
||||||
|
$stack = X509Stack::from($this->ffi, $this->data->cert, $this);
|
||||||
|
$stack->unmanaged();
|
||||||
|
return $stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verify(string $plain, int $flags, ?X509Store $x509Store = null)
|
||||||
|
{
|
||||||
|
if ($x509Store === null) {
|
||||||
|
$x509Store = OpenSSL::CAStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
$buffer = BIO::buffer($plain);
|
||||||
|
$x = $this->ffi->PKCS7_verify($this->parent, null, $x509Store->getCData(), $buffer->getCData(), null, $flags);
|
||||||
|
return $x === 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
src/OpenSSL/PKCS7/SignerInfo.php
Normal file
9
src/OpenSSL/PKCS7/SignerInfo.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace Cijber\OpenSSL\PKCS7;
|
||||||
|
|
||||||
|
class SignerInfo
|
||||||
|
{
|
||||||
|
const TYPE = "PKCS7_SIGNER_INFO*";
|
||||||
|
}
|
16
src/OpenSSL/PKCS7/Stack/SignerInfoStack.php
Normal file
16
src/OpenSSL/PKCS7/Stack/SignerInfoStack.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace Cijber\OpenSSL\PKCS7\Stack;
|
||||||
|
|
||||||
|
use Cijber\OpenSSL\PKCS7\SignerInfo;
|
||||||
|
use Cijber\OpenSSL\Stack;
|
||||||
|
use FFI\CData;
|
||||||
|
|
||||||
|
class SignerInfoStack extends Stack
|
||||||
|
{
|
||||||
|
protected function spawn(CData $cData): SignerInfo
|
||||||
|
{
|
||||||
|
// TODO: Implement spawn() method.
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ use Cijber\OpenSSL;
|
||||||
use Cijber\OpenSSL\C\CBackedObject;
|
use Cijber\OpenSSL\C\CBackedObject;
|
||||||
use Cijber\OpenSSL\C\CBackedObjectWithOwner;
|
use Cijber\OpenSSL\C\CBackedObjectWithOwner;
|
||||||
use Countable;
|
use Countable;
|
||||||
|
use FFI;
|
||||||
use FFI\CData;
|
use FFI\CData;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use IteratorAggregate;
|
use IteratorAggregate;
|
||||||
|
@ -21,9 +22,18 @@ use Traversable;
|
||||||
abstract class Stack extends CBackedObjectWithOwner implements Countable, ArrayAccess, Traversable, IteratorAggregate
|
abstract class Stack extends CBackedObjectWithOwner implements Countable, ArrayAccess, Traversable, IteratorAggregate
|
||||||
{
|
{
|
||||||
const CLASSNAME = CBackedObjectWithOwner::class;
|
const CLASSNAME = CBackedObjectWithOwner::class;
|
||||||
|
const TYPE = "struct stack_st*";
|
||||||
|
|
||||||
abstract protected function spawn(CData $cData);
|
abstract protected function spawn(CData $cData);
|
||||||
|
|
||||||
|
protected $owner;
|
||||||
|
|
||||||
|
protected function __construct(FFI $ffi, CData $cObj, $owner = null)
|
||||||
|
{
|
||||||
|
parent::__construct($ffi, $ffi->cast(self::TYPE, $cObj));
|
||||||
|
$this->owner = $owner;
|
||||||
|
}
|
||||||
|
|
||||||
public static function new()
|
public static function new()
|
||||||
{
|
{
|
||||||
$ffi = OpenSSL::getFFI();
|
$ffi = OpenSSL::getFFI();
|
||||||
|
@ -100,8 +110,6 @@ abstract class Stack extends CBackedObjectWithOwner implements Countable, ArrayA
|
||||||
throw new RuntimeException("Failed to insert element");
|
throw new RuntimeException("Failed to insert element");
|
||||||
}
|
}
|
||||||
|
|
||||||
$object->pushRefCount();
|
|
||||||
|
|
||||||
return $idx;
|
return $idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +196,9 @@ abstract class Stack extends CBackedObjectWithOwner implements Countable, ArrayA
|
||||||
|
|
||||||
public function __clone()
|
public function __clone()
|
||||||
{
|
{
|
||||||
$cObj = $this->ffi->sk_dup($this->cObj);
|
$this->cObj = $this->ffi->sk_dup($this->cObj);
|
||||||
|
|
||||||
if ($cObj === null) {
|
if ($this->cObj === null) {
|
||||||
throw new RuntimeException("Failed to clone stack");
|
throw new RuntimeException("Failed to clone stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +206,5 @@ abstract class Stack extends CBackedObjectWithOwner implements Countable, ArrayA
|
||||||
foreach ($this as $obj) {
|
foreach ($this as $obj) {
|
||||||
$obj->pushRefCount();
|
$obj->pushRefCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new static($this->ffi, $cObj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,18 @@ class X509Stack extends Stack
|
||||||
{
|
{
|
||||||
const CLASSNAME = X509::class;
|
const CLASSNAME = X509::class;
|
||||||
|
|
||||||
public static function from(FFI $ffi, CData $cObj): X509Stack
|
public static function from(FFI $ffi, CData $cObj, $owner = null): X509Stack
|
||||||
{
|
{
|
||||||
return new X509Stack($ffi, $cObj);
|
return new X509Stack($ffi, $cObj, $owner = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function spawn(CData $cData): X509
|
public function spawn(CData $cData): X509
|
||||||
{
|
{
|
||||||
return X509::cast($this->ffi, $cData);
|
$obj = $this->ffi->cast(X509::TYPE, $cData);
|
||||||
|
$clone = $this->ffi->X509_dup($obj);
|
||||||
|
if ($clone === null) {
|
||||||
|
return X509::new();
|
||||||
|
}
|
||||||
|
return X509::cast($this->ffi, $clone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,12 @@ namespace Cijber\OpenSSL;
|
||||||
|
|
||||||
use Cijber\OpenSSL;
|
use Cijber\OpenSSL;
|
||||||
use Cijber\OpenSSL\C\CBackedObjectWithOwner;
|
use Cijber\OpenSSL\C\CBackedObjectWithOwner;
|
||||||
|
use FFI;
|
||||||
|
|
||||||
class X509 extends CBackedObjectWithOwner
|
class X509 extends CBackedObjectWithOwner
|
||||||
{
|
{
|
||||||
|
const FILETYPE_DEFAULT = 3;
|
||||||
|
|
||||||
const TYPE = "X509*";
|
const TYPE = "X509*";
|
||||||
|
|
||||||
public static function new(): X509
|
public static function new(): X509
|
||||||
|
@ -21,4 +24,15 @@ class X509 extends CBackedObjectWithOwner
|
||||||
{
|
{
|
||||||
$this->ffi->X509_free($this->cObj);
|
$this->ffi->X509_free($this->cObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return FFI::string($this->cObj->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSHA1Hash()
|
||||||
|
{
|
||||||
|
$hash = FFI::string($this->cObj->sha1_hash, 20);
|
||||||
|
return $hash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,24 @@ class X509Store extends CBackedObjectWithOwner
|
||||||
return new X509Store($ffi, $x509);
|
return new X509Store($ffi, $x509);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function default(): X509Store
|
||||||
|
{
|
||||||
|
$store = X509Store::new();
|
||||||
|
$obj = $store->cObj;
|
||||||
|
$ffi = $store->ffi;
|
||||||
|
$lookup = $ffi->X509_STORE_add_lookup($obj, $ffi->X509_LOOKUP_file());
|
||||||
|
if ($lookup === null || !$ffi->X509_LOOKUP_ctrl($lookup, 1, null, X509::FILETYPE_DEFAULT, null)) {
|
||||||
|
throw new \RuntimeException("Couldn't load default CA files");
|
||||||
|
}
|
||||||
|
|
||||||
|
$lookup = $ffi->X509_STORE_add_lookup($obj, $ffi->X509_LOOKUP_hash_dir());
|
||||||
|
if ($lookup === null || !$ffi->X509_LOOKUP_ctrl($lookup, 2, null, X509::FILETYPE_DEFAULT, null)) {
|
||||||
|
throw new \RuntimeException("Couldn't load default CA files");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $store;
|
||||||
|
}
|
||||||
|
|
||||||
public function freeObject()
|
public function freeObject()
|
||||||
{
|
{
|
||||||
$this->ffi->X509_STORE_free($this->cObj);
|
$this->ffi->X509_STORE_free($this->cObj);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Cijber\OpenSSL\Tests;
|
namespace Cijber\OpenSSL\Tests;
|
||||||
|
|
||||||
use Cijber\OpenSSL\PKCS7;
|
use Cijber\OpenSSL\PKCS7;
|
||||||
|
use Cijber\OpenSSL\X509;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
|
@ -22,6 +23,22 @@ class PKCS7Test extends TestCase
|
||||||
$newDer = $pkcs7->toDER();
|
$newDer = $pkcs7->toDER();
|
||||||
$this->assertEquals(PKCS7::NID_SIGNED, $pkcs7->getType());
|
$this->assertEquals(PKCS7::NID_SIGNED, $pkcs7->getType());
|
||||||
$this->assertEquals($der, $newDer);
|
$this->assertEquals($der, $newDer);
|
||||||
|
$signed = $pkcs7->asSigned();
|
||||||
|
$certs = $signed->getCerts();
|
||||||
|
$this->assertCount(1, $certs);
|
||||||
|
/** @var X509 $x509 */
|
||||||
|
$x509 = $certs[0];
|
||||||
|
$x = $x509->getName();
|
||||||
|
$this->assertEquals("/C=US/ST=New York/L=New York/OU=FDroid Repo/O=Guardian Project/CN=guardianproject.info/emailAddress=root@guardianproject.info", $x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testVerify() {
|
||||||
|
$der = file_get_contents(__DIR__ . "/data/pkcs7/1.RSA");
|
||||||
|
$plain = file_get_contents(__DIR__ . "/data/pkcs7/1.SF");
|
||||||
|
$pkcs7 = PKCS7::loadFromDER($der);
|
||||||
|
$signed = $pkcs7->asSigned();
|
||||||
|
$result = $signed->verify($plain, PKCS7_NOVERIFY);
|
||||||
|
$this->assertTrue($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadingGarbageDER()
|
public function testLoadingGarbageDER()
|
||||||
|
|
|
@ -24,7 +24,7 @@ class StackTest extends TestCase
|
||||||
$stack->push($x509);
|
$stack->push($x509);
|
||||||
$this->assertCount(1, $stack);
|
$this->assertCount(1, $stack);
|
||||||
$x509Item = $stack->get(0);
|
$x509Item = $stack->get(0);
|
||||||
$this->assertSame($x509, $x509Item);
|
$this->assertNotSame($x509, $x509Item);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSet()
|
function testSet()
|
||||||
|
@ -47,14 +47,10 @@ class StackTest extends TestCase
|
||||||
$c = X509::new();
|
$c = X509::new();
|
||||||
$stack->push($a);
|
$stack->push($a);
|
||||||
$stack->push($c);
|
$stack->push($c);
|
||||||
$this->assertEquals(1, $a->getRefCount());
|
|
||||||
$b = $stack->delete(0);
|
$b = $stack->delete(0);
|
||||||
$this->assertSame($a, $b);
|
|
||||||
$this->assertCount(1, $stack);
|
$this->assertCount(1, $stack);
|
||||||
$this->assertEquals(0, $a->getRefCount());
|
|
||||||
unset($stack[0]);
|
unset($stack[0]);
|
||||||
$this->assertCount(0, $stack);
|
$this->assertCount(0, $stack);
|
||||||
$this->assertEquals(0, $c->getRefCount());
|
|
||||||
|
|
||||||
$this->expectException(\RuntimeException::class);
|
$this->expectException(\RuntimeException::class);
|
||||||
$stack->delete(1);
|
$stack->delete(1);
|
||||||
|
@ -67,17 +63,13 @@ class StackTest extends TestCase
|
||||||
$stack->push($x509);
|
$stack->push($x509);
|
||||||
$this->assertCount(1, $stack);
|
$this->assertCount(1, $stack);
|
||||||
$x509Item = $stack->get(0);
|
$x509Item = $stack->get(0);
|
||||||
$this->assertSame($x509, $x509Item);
|
|
||||||
$this->assertEquals(1, $x509->getRefCount());
|
|
||||||
unset($x509Item, $x509);
|
unset($x509Item, $x509);
|
||||||
|
|
||||||
/** @var X509 $x509 */
|
/** @var X509 $x509 */
|
||||||
$x509 = $stack->get(0);
|
$x509 = $stack->get(0);
|
||||||
$this->assertFalse($x509->free());
|
|
||||||
$stack->freeAll();
|
$stack->freeAll();
|
||||||
$this->assertEquals(0, $x509->getRefCount());
|
|
||||||
$this->assertTrue($stack->isFreed());
|
$this->assertTrue($stack->isFreed());
|
||||||
$this->assertTrue($x509->isFreed());
|
$this->assertFalse($x509->isFreed());
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAddressingCorrect()
|
function testAddressingCorrect()
|
||||||
|
|
Loading…
Reference in a new issue