* TSTInfo ::= SEQUENCE { * version INTEGER { v1(1) }, * policy TSAPolicyId, * messageImprint MessageImprint, * serialNumber INTEGER, * genTime GeneralizedTime, * accuracy Accuracy OPTIONAL, * ordering BOOLEAN DEFAULT FALSE, * nonce INTEGER OPTIONAL, * tsa [0] GeneralName OPTIONAL, * extensions [1] IMPLICIT Extensions OPTIONAL * } * * * @package asn1 * @subpackage tsp * * @link http://tools.ietf.org/html/rfc3161#section-2.4.2 RFC 3161: Time-Stamp Protocol */ class TSPTSTInfo implements ASN1DEREncodable { /** * Object identifier for the TSTInfo content type. */ const OID = "1.2.840.113549.1.9.16.1.4"; private $version; private $policy; private $messageImprint; private $serialNumber; private $genTime; private $accuracy; private $ordering; private $nonce; private $tsa; private $extensions; /** * Constructs a new instance of TSPTSTInfo. */ public function __construct() { } /** * Decodes the given ASN1Sequence as TSPTSTInfo. * * @throws GTException * @param ASN1Sequence $object TSPTSTInfo encoded as ASN1Sequence * @return void */ public function decode($object) { if (!$object instanceof ASN1Sequence) { throw new GTException("Expecting an ASN1Sequence"); } $size = $object->getObjectCount(); if ($size < 5 || $size > 10) { throw new GTException("Invalid sequence size: {$size}"); } $version = $object->getObjectAt(0); if (!$version instanceof ASN1Integer) { throw new GTException("Expecting an ASN1Integer"); } $this->version = (int) $version->getValue(); if ($this->version !== 1) { throw new GTException("Invalid version: {$this->version}"); } $policy = $object->getObjectAt(1); if (!$policy instanceof ASN1ObjectId) { throw new GTException("Expecting an ASN1ObjectId"); } $this->policy = $policy->getValue(); $messageImprint = new TSPMessageImprint(); $messageImprint->decode($object->getObjectAt(2)); $this->messageImprint = $messageImprint; $serialNumber = $object->getObjectAt(3); if (!$serialNumber instanceof ASN1Integer) { throw new GTException("Expecting an ASN1Integer"); } $this->serialNumber = $serialNumber->getValue(); $genTime = $object->getObjectAt(4); if (!$genTime instanceof ASN1GeneralizedTime) { throw new GTException("Expecting an ASN1GeneralizedTime"); } $this->genTime = $genTime->getValue(); $this->ordering = false; for ($i = 5; $i < $object->getObjectCount(); $i++) { $item = $object->getObjectAt($i); if ($item instanceof ASN1Sequence) { // accuracy $accuracy = new TSPAccuracy(); $accuracy->decode($item); $this->accuracy = $accuracy; } else if ($item instanceof ASN1Boolean) { // ordering $this->ordering = $item->getValue(); } else if ($item instanceof ASN1Integer) { // nonce $this->nonce = $item->getValue(); } else if ($item instanceof ASN1Tag) { switch ($item->getTagValue()) { case 0: // tsa $tsa = new X509GeneralName(); $tsa->decode($item->getObject()); $this->tsa = $tsa; break; case 1: // extensions $set = $item->getObjectAs(ASN1_TAG_SET); $this->extensions = array(); for ($i = 0; $i < $set->getObjectCount(); $i++) { $extension = new X509Extension(); $extension->decode($set->getObjectAt($i)); array_push($this->extensions, $extension); } foreach ($this->extensions as $extension) { if ($extension->isCritical()) { throw new GTException("Unknown critical extension present: {$extension->getId()}"); } } break; default: throw new GTException("Unknown TAG in TSTINFO: " . $item->getTagValue()); } } else { throw new GTException("Unknown element in TSTINFO: " . get_class($item)); } } } /** * Encodes this TSPTSTInfo using DER. * * @return array byte array containing the DER encoding of this TSPTSTInfo */ public function encodeDER() { $sequence = new ASN1Sequence(); $sequence->add(new ASN1Integer((int) $this->version)); $sequence->add(new ASN1ObjectId($this->policy)); $sequence->add($this->messageImprint); $sequence->add(new ASN1Integer($this->serialNumber)); $sequence->add(new ASN1GeneralizedTime($this->genTime)); if ($this->accuracy != null) { $sequence->add($this->accuracy); } if ($this->ordering === true) { $sequence->add(new ASN1Boolean($this->ordering)); } if ($this->nonce != null) { $sequence->add(new ASN1Integer($this->nonce)); } if ($this->tsa != null) { $tag = new ASN1Tag(); $tag->setTagValue(0); $tag->setExplicit(true); $tag->setTagClass(ASN1_TAG_CONTEXT); $tag->setTagType(ASN1_TAG_CONSTRUCTED); $tag->setObject($this->tsa); $sequence->add($tag); } if ($this->extensions != null) { $set = new ASN1Set(); foreach ($this->extensions as $extension) { $set->add($extension); } $tag = new ASN1Tag(); $tag->setTagValue(1); $tag->setExplicit(false); $tag->setTagClass(ASN1_TAG_CONTEXT); $tag->setTagType(ASN1_TAG_CONSTRUCTED); $tag->setObject($set); $sequence->add($tag); } return $sequence->encodeDER(); } /** * Gets the message imprint. * * @return TSPMessageImprint the message imprint */ public function getMessageImprint() { return $this->messageImprint; } /** * Gets the policy. * * @return string oid */ public function getPolicy() { return $this->policy; } /** * Gets the serial number. * * @return string serial number */ public function getSerialNumber() { return $this->serialNumber; } /** * Gets the generalized time. * * @return string generalized time */ public function getGenTime() { return $this->genTime; } /** * Gets the accuracy. * * @return TSPAccuracy accuracy */ public function getAccuracy() { return $this->accuracy; } /** * Gets the TSA. * * @return X509GeneralName tsa */ public function getTsa() { return $this->tsa; } /** * Gets the TSA formatted as string. * * @return string formatted tsa */ public function getFormattedTsa() { if ($this->tsa == null) { return null; } return $this->tsa->getFormatted(); } } ?>