1<?php 2/* 3 * Copyright 2008-2010 GuardTime AS 4 * 5 * This file is part of the GuardTime PHP SDK. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20/** 21 * @package asn1 22 * @subpackage tsp 23 */ 24 25/** 26 * TSP TSTInfo implementation. 27 * 28 * <pre> 29 * TSTInfo ::= SEQUENCE { 30 * version INTEGER { v1(1) }, 31 * policy TSAPolicyId, 32 * messageImprint MessageImprint, 33 * serialNumber INTEGER, 34 * genTime GeneralizedTime, 35 * accuracy Accuracy OPTIONAL, 36 * ordering BOOLEAN DEFAULT FALSE, 37 * nonce INTEGER OPTIONAL, 38 * tsa [0] GeneralName OPTIONAL, 39 * extensions [1] IMPLICIT Extensions OPTIONAL 40 * } 41 * </pre> 42 * 43 * @package asn1 44 * @subpackage tsp 45 * 46 * @link http://tools.ietf.org/html/rfc3161#section-2.4.2 RFC 3161: Time-Stamp Protocol 47 */ 48class TSPTSTInfo implements ASN1DEREncodable { 49 50 /** 51 * Object identifier for the TSTInfo content type. 52 */ 53 const OID = "1.2.840.113549.1.9.16.1.4"; 54 55 private $version; 56 private $policy; 57 private $messageImprint; 58 private $serialNumber; 59 private $genTime; 60 private $accuracy; 61 private $ordering; 62 private $nonce; 63 private $tsa; 64 private $extensions; 65 66 /** 67 * Constructs a new instance of TSPTSTInfo. 68 */ 69 public function __construct() { 70 } 71 72 /** 73 * Decodes the given ASN1Sequence as TSPTSTInfo. 74 * 75 * @throws GTException 76 * @param ASN1Sequence $object TSPTSTInfo encoded as ASN1Sequence 77 * @return void 78 */ 79 public function decode($object) { 80 81 if (!$object instanceof ASN1Sequence) { 82 throw new GTException("Expecting an ASN1Sequence"); 83 } 84 85 $size = $object->getObjectCount(); 86 87 if ($size < 5 || $size > 10) { 88 throw new GTException("Invalid sequence size: {$size}"); 89 } 90 91 $version = $object->getObjectAt(0); 92 93 if (!$version instanceof ASN1Integer) { 94 throw new GTException("Expecting an ASN1Integer"); 95 } 96 97 $this->version = (int) $version->getValue(); 98 99 if ($this->version !== 1) { 100 throw new GTException("Invalid version: {$this->version}"); 101 } 102 103 $policy = $object->getObjectAt(1); 104 105 if (!$policy instanceof ASN1ObjectId) { 106 throw new GTException("Expecting an ASN1ObjectId"); 107 } 108 109 $this->policy = $policy->getValue(); 110 111 $messageImprint = new TSPMessageImprint(); 112 $messageImprint->decode($object->getObjectAt(2)); 113 114 $this->messageImprint = $messageImprint; 115 116 $serialNumber = $object->getObjectAt(3); 117 118 if (!$serialNumber instanceof ASN1Integer) { 119 throw new GTException("Expecting an ASN1Integer"); 120 } 121 122 $this->serialNumber = $serialNumber->getValue(); 123 124 $genTime = $object->getObjectAt(4); 125 126 if (!$genTime instanceof ASN1GeneralizedTime) { 127 throw new GTException("Expecting an ASN1GeneralizedTime"); 128 } 129 130 $this->genTime = $genTime->getValue(); 131 132 $this->ordering = false; 133 134 for ($i = 5; $i < $object->getObjectCount(); $i++) { 135 136 $item = $object->getObjectAt($i); 137 138 if ($item instanceof ASN1Sequence) { 139 140 // accuracy 141 142 $accuracy = new TSPAccuracy(); 143 $accuracy->decode($item); 144 145 $this->accuracy = $accuracy; 146 147 } else if ($item instanceof ASN1Boolean) { 148 149 // ordering 150 $this->ordering = $item->getValue(); 151 152 } else if ($item instanceof ASN1Integer) { 153 154 // nonce 155 $this->nonce = $item->getValue(); 156 157 } else if ($item instanceof ASN1Tag) { 158 159 switch ($item->getTagValue()) { 160 161 case 0: 162 163 // tsa 164 $tsa = new X509GeneralName(); 165 $tsa->decode($item->getObject()); 166 167 $this->tsa = $tsa; 168 169 break; 170 171 case 1: 172 173 // extensions 174 $set = $item->getObjectAs(ASN1_TAG_SET); 175 176 $this->extensions = array(); 177 178 for ($i = 0; $i < $set->getObjectCount(); $i++) { 179 180 $extension = new X509Extension(); 181 $extension->decode($set->getObjectAt($i)); 182 183 array_push($this->extensions, $extension); 184 } 185 186 foreach ($this->extensions as $extension) { 187 if ($extension->isCritical()) { 188 throw new GTException("Unknown critical extension present: {$extension->getId()}"); 189 } 190 } 191 192 break; 193 194 default: 195 196 throw new GTException("Unknown TAG in TSTINFO: " . $item->getTagValue()); 197 } 198 199 } else { 200 201 throw new GTException("Unknown element in TSTINFO: " . get_class($item)); 202 203 } 204 205 } 206 } 207 208 /** 209 * Encodes this TSPTSTInfo using DER. 210 * 211 * @return array byte array containing the DER encoding of this TSPTSTInfo 212 */ 213 public function encodeDER() { 214 215 $sequence = new ASN1Sequence(); 216 217 $sequence->add(new ASN1Integer((int) $this->version)); 218 $sequence->add(new ASN1ObjectId($this->policy)); 219 $sequence->add($this->messageImprint); 220 $sequence->add(new ASN1Integer($this->serialNumber)); 221 $sequence->add(new ASN1GeneralizedTime($this->genTime)); 222 223 if ($this->accuracy != null) { 224 $sequence->add($this->accuracy); 225 } 226 227 if ($this->ordering === true) { 228 $sequence->add(new ASN1Boolean($this->ordering)); 229 } 230 231 if ($this->nonce != null) { 232 $sequence->add(new ASN1Integer($this->nonce)); 233 } 234 235 if ($this->tsa != null) { 236 $tag = new ASN1Tag(); 237 $tag->setTagValue(0); 238 $tag->setExplicit(true); 239 $tag->setTagClass(ASN1_TAG_CONTEXT); 240 $tag->setTagType(ASN1_TAG_CONSTRUCTED); 241 $tag->setObject($this->tsa); 242 243 $sequence->add($tag); 244 245 } 246 247 if ($this->extensions != null) { 248 249 $set = new ASN1Set(); 250 251 foreach ($this->extensions as $extension) { 252 $set->add($extension); 253 } 254 255 $tag = new ASN1Tag(); 256 $tag->setTagValue(1); 257 $tag->setExplicit(false); 258 $tag->setTagClass(ASN1_TAG_CONTEXT); 259 $tag->setTagType(ASN1_TAG_CONSTRUCTED); 260 $tag->setObject($set); 261 262 $sequence->add($tag); 263 } 264 265 return $sequence->encodeDER(); 266 } 267 268 /** 269 * Gets the message imprint. 270 * 271 * @return TSPMessageImprint the message imprint 272 */ 273 public function getMessageImprint() { 274 return $this->messageImprint; 275 } 276 277 /** 278 * Gets the policy. 279 * 280 * @return string oid 281 */ 282 public function getPolicy() { 283 return $this->policy; 284 } 285 286 /** 287 * Gets the serial number. 288 * 289 * @return string serial number 290 */ 291 public function getSerialNumber() { 292 return $this->serialNumber; 293 } 294 295 /** 296 * Gets the generalized time. 297 * 298 * @return string generalized time 299 */ 300 public function getGenTime() { 301 return $this->genTime; 302 } 303 304 /** 305 * Gets the accuracy. 306 * 307 * @return TSPAccuracy accuracy 308 */ 309 public function getAccuracy() { 310 return $this->accuracy; 311 } 312 313 /** 314 * Gets the TSA. 315 * 316 * @return X509GeneralName tsa 317 */ 318 public function getTsa() { 319 return $this->tsa; 320 } 321 322 /** 323 * Gets the TSA formatted as string. 324 * 325 * @return string formatted tsa 326 */ 327 public function getFormattedTsa() { 328 329 if ($this->tsa == null) { 330 return null; 331 } 332 333 return $this->tsa->getFormatted(); 334 } 335 336} 337 338?> 339