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 Accuracy implementation. 27 * 28 * <pre> 29 * Accuracy ::= SEQUENCE { 30 * seconds INTEGER OPTIONAL, 31 * millis [0] INTEGER (1..999) OPTIONAL, 32 * micros [1] INTEGER (1..999) OPTIONAL 33 * } 34 * </pre> 35 * 36 * @package asn1 37 * @subpackage tsp 38 * 39 * @link http://tools.ietf.org/html/rfc3161#section-2.4.2 RFC 3161: Time-Stamp Protocol 40 */ 41class TSPAccuracy implements ASN1DEREncodable { 42 43 private $seconds; 44 private $millis; 45 private $micros; 46 47 /** 48 * Constructs a new isntance of TSPAccuracy. 49 */ 50 public function __construct() { 51 } 52 53 /** 54 * Decodes the given ASN1Sequence as TSPAccuracy. 55 * 56 * @throws GTException 57 * @param ASN1Sequence $object TSPAccuracy encoded as ASN1Sequence 58 * @return void 59 */ 60 public function decode($object) { 61 62 if (!$object instanceof ASN1Sequence) { 63 throw new GTException("Expecting an ASN1Sequence"); 64 } 65 66 if ($object->getObjectCount() < 1 || $object->getObjectCount() > 3) { 67 throw new GTException("Invalid number of elements in sequence"); 68 } 69 70 for ($i = 0; $i < $object->getObjectCount(); $i++) { 71 72 $item = $object->getObjectAt($i); 73 74 if ($item instanceof ASN1Integer) { 75 76 if (!is_null($this->seconds)) { 77 throw new GTException("Unexpected ASN1Integer: {$item->getValue()}"); 78 } 79 80 if ($i != 0) { 81 throw new GTException("Unexpected ASN1Integer: {$item->getValue()}"); 82 } 83 84 $this->seconds = $item->getValue(); 85 86 } else if ($item instanceof ASN1Tag) { 87 88 switch ($item->getTagValue()) { 89 90 case 0: 91 92 // millis 93 94 if (!is_null($this->millis)) { 95 throw new GTException("Unexpected TAG value: 0"); 96 } 97 98 $millis = $item->getObjectAs(ASN1_TAG_INTEGER); 99 100 if (!$millis instanceof ASN1Integer) { 101 throw new GTException("Expecting an ASN1Integer"); 102 } 103 104 if ((int) $millis->getValue() < 1) { 105 throw new GTException("Invalid value for millis: {$millis->getValue()}"); 106 } 107 108 if ((int) $millis->getValue() > 999) { 109 throw new GTException("Invalid value for millis: {$millis->getValue()}"); 110 } 111 112 $this->millis = $millis->getValue(); 113 114 break; 115 116 case 1: 117 118 // micros 119 120 if (!is_null($this->micros)) { 121 throw new GTException("Unexpected TAG value: 1"); 122 } 123 124 $micros = $item->getObjectAs(ASN1_TAG_INTEGER); 125 126 if (!$micros instanceof ASN1Integer) { 127 throw new GTException("Expecting an ASN1Integer"); 128 } 129 130 if ((int) $micros->getValue() < 1) { 131 throw new GTException("Invalid value for micros: {$micros->getValue()}"); 132 } 133 134 if ((int) $micros->getValue() > 999) { 135 throw new GTException("Invalid value for micros: {$micros->getValue()}"); 136 } 137 138 $this->micros = $micros->getValue(); 139 140 default: 141 throw new GTException("Unexpected TAG value: {$item->getTagValue()}"); 142 143 } 144 145 } else { 146 throw new GTException("Unexpected ASN1 type: " . get_class($item)); 147 148 } 149 150 } 151 152 } 153 154 /** 155 * Encodes this TSPAccuracy using DER. 156 * 157 * @return array byte array that contains the DER encoding of this TSPAccuracy 158 */ 159 public function encodeDER() { 160 161 $sequence = new ASN1Sequence(); 162 163 if ($this->seconds != null) { 164 $sequence->add(new ASN1Integer($this->seconds)); 165 } 166 167 if ($this->millis != null) { 168 $tag = new ASN1Tag(); 169 $tag->setExplicit(true); 170 $tag->setTagClass(ASN1_TAG_CONTEXT); 171 $tag->setTagType(ASN1_TAG_CONSTRUCTED); 172 $tag->setTagValue(0); 173 $tag->setObject(new ASN1Integer($this->millis)); 174 175 $sequence->add($tag); 176 } 177 178 if ($this->micros != null) { 179 $tag = new ASN1Tag(); 180 $tag->setExplicit(true); 181 $tag->setTagClass(ASN1_TAG_CONTEXT); 182 $tag->setTagType(ASN1_TAG_CONSTRUCTED); 183 $tag->setTagValue(1); 184 $tag->setObject(new ASN1Integer($this->micros)); 185 186 $sequence->add($tag); 187 } 188 189 return $sequence->encodeDER(); 190 191 } 192 193 /** 194 * Gets this TSPAccuracy formatted as string. 195 * 196 * @return string formatted TSPAccuracy 197 */ 198 public function getFormatted() { 199 200 $accuracy = new GTBigInteger(0); 201 202 if (!is_null($this->seconds)) { 203 $accuracy = $accuracy->add(new GTBigInteger($this->seconds)); 204 } 205 206 $accuracy = $accuracy->mul(new GTBigInteger(1000)); 207 208 if (!is_null($this->millis)) { 209 $accuracy = $accuracy->add(new GTBigInteger($this->millis)); 210 } 211 212 $accuracy = $accuracy->mul(new GTBigInteger(1000)); 213 214 if (!is_null($this->micros)) { 215 $accuracy = $accuracy->add(new GTBigInteger($this->micros)); 216 } 217 218 $zero = new GTBigInteger(0); 219 220 if ($accuracy->mod(1000000)->comp($zero) == 0) { 221 return "{$accuracy->div(new GTBigInteger(1000000))->getValue()}s"; 222 223 } else if ($accuracy->mod(1000)->comp($zero) == 0) { 224 return "{$accuracy->div(new GTBigInteger(1000))->getValue()}ms"; 225 226 } else { 227 return "{$accuracy->getValue()}us"; 228 229 } 230 } 231 232} 233 234?> 235