1<?php 2/* 3 * 4 * Copyright 2008-2010 GuardTime AS 5 * 6 * This file is part of the GuardTime PHP SDK. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 */ 21 22/** 23 * @package http 24 */ 25 26/** 27 * A collection of static methods for basic operations with timestamps. 28 * 29 * @package http 30 */ 31class GTHttpClient { 32 33 /** 34 * Creates timestamp for the given dataHash using stamperUrl. 35 * 36 * @static 37 * @throws GTException thrown if timestamp creation fails 38 * @param GTDataHash $dataHash data hash to create the timestamp for 39 * @param string $stamperUrl stamping service url 40 * @return GTTimestamp a newly created short-term (signed) timestamp 41 */ 42 public static function create(GTDataHash $dataHash, $stamperUrl) { 43 44 $algorithm = new X509AlgorithmIdentifier(); 45 $algorithm->setAlgorithm($dataHash->getHashAlgorithm()->getOid()); 46 47 $message = new TSPMessageImprint(); 48 $message->setHashedMessage($dataHash->getHashedMessage()); 49 $message->setHashAlgorithm($algorithm); 50 51 $request = new TSPTimeStampReq(); 52 $request->setMessageImprint($message); 53 54 $bytes = $request->encodeDER(); 55 $bytes = GTUtil::fromByteArray($bytes); 56 57 $curl = curl_init(); 58 59 curl_setopt($curl, CURLOPT_URL, $stamperUrl); 60 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 61 curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); 62 curl_setopt($curl, CURLOPT_POST, 1); 63 curl_setopt($curl, CURLOPT_POSTFIELDS, $bytes); 64 65 $bytes = curl_exec($curl); 66 67 if ($bytes === false) { 68 throw new GTException("Error creating timestamp, CURL error: " . curl_error($curl)); 69 } 70 71 $bytes = GTUtil::toByteArray($bytes); 72 73 $response = new TSPTimeStampResp(); 74 $response->decode(ASN1DER::decode($bytes)); 75 76 return new GTTimestamp($response->getToken()); 77 } 78 79 /** 80 * Extends the timestamp using the given extension service URL. 81 * 82 * @static 83 * @throws GTException if timestamp extension fails 84 * @param GTTimestamp $timestamp timestamp to be extended 85 * @param string $verifierUrl extension service URL 86 * @return void 87 */ 88 public static function extend(GTTimestamp $timestamp, $verifierUrl) { 89 90 $request = new GTCertTokenRequest(); 91 $request->setHistoryIdentifier(new GTBigInteger($timestamp->getProperty(GTTimestamp::HISTORY_ID))); 92 93 $bytes = $request->encodeDER(); 94 $bytes = GTUtil::fromByteArray($bytes); 95 96 $curl = curl_init(); 97 98 curl_setopt($curl, CURLOPT_URL, $verifierUrl); 99 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 100 curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); 101 curl_setopt($curl, CURLOPT_POST, 1); 102 curl_setopt($curl, CURLOPT_POSTFIELDS, $bytes); 103 104 $bytes = curl_exec($curl); 105 106 if ($bytes === false) { 107 throw new GTException("Error extending timestamp, CURL error: " . curl_error($curl)); 108 } 109 110 $bytes = GTUtil::toByteArray($bytes); 111 112 $response = new GTCertTokenResponse(); 113 $response->decode(ASN1DER::decode($bytes)); 114 115 $timestamp->extend($response); 116 117 } 118 119 /** 120 * Verifies the given timestamp against the given dataHash. 121 * 122 * If a timestamp is not yet extended, automatic extension is attempted. 123 * If the automatic extension is successfull the extended timestamp is verified 124 * against the given publicationsFile. 125 * 126 * If the timestamp is already extended then the timestamp is verified against 127 * the given publications file. 128 * 129 * If the timestamp is not extended and extension is not possible the timestamp 130 * will be verified against short term signing certificates. 131 * 132 * @static 133 * @throws GTException 134 * @param GTTimestamp $timestamp the timestamp to verify 135 * @param GTDataHash $dataHash data hash to verify the timestamp against 136 * @param null|string $verifierUrl extension url if automatic extension is to be attempted, null otherwise 137 * @param GTPublicationsFile $publicationsFile publications file to verify the timestamp against 138 * 139 * @return GTVerificationResultHttp tmestamp verification result 140 */ 141 public static function verify(GTTimestamp $timestamp, GTDataHash $dataHash, $verifierUrl, GTPublicationsFile $publicationsFile) { 142 143 if (empty($timestamp)) { 144 throw new GTException("Parameter timestamp is required"); 145 } 146 147 if (empty($dataHash)) { 148 throw new GTException("Parameter dataHash is required"); 149 } 150 151 if ($publicationsFile == null) { 152 throw new GTException("Invalid publications file: null"); 153 } 154 155 $result = new GTVerificationResultHttp(); 156 157 if ($verifierUrl === null) { 158 $extendable = false; 159 160 } else { 161 $extendable = $timestamp->isExtendable($publicationsFile); 162 163 } 164 165 if ($extendable) { 166 167 $result->updateStatus(GTVerificationResultHttp::EXTENSION_ATTEMPTED); 168 169 $request = new GTCertTokenRequest(); 170 $request->setHistoryIdentifier(new GTBigInteger($timestamp->getProperty(GTTimestamp::HISTORY_ID))); 171 172 $bytes = $request->encodeDER(); 173 $bytes = GTUtil::fromByteArray($bytes); 174 175 $curl = curl_init(); 176 177 curl_setopt($curl, CURLOPT_URL, $verifierUrl); 178 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 179 curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); 180 curl_setopt($curl, CURLOPT_POST, 1); 181 curl_setopt($curl, CURLOPT_POSTFIELDS, $bytes); 182 183 $bytes = curl_exec($curl); 184 185 if ($bytes === false) { 186 $result->updateStatus(GTVerificationResultHttp::SERVICE_UNREACHABLE_FAILURE); 187 } 188 189 $bytes = GTUtil::toByteArray($bytes); 190 191 $response = null; 192 193 try { 194 $response = new GTCertTokenResponse(); 195 $response->decode(ASN1DER::decode($bytes)); 196 197 } catch (GTException $e) { 198 $result->updateStatus(GTVerificationResultHttp::RESPONSE_FORMAT_FAILURE); 199 return $result; 200 } 201 202 $statusCode = ($response === null) ? -1 : $response->getStatusCode(); 203 204 if ($statusCode == 0) { 205 $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_GRANTED); 206 207 } else if ($statusCode == 1) { 208 $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_GRANTED_WITH_MODS); 209 210 } else if ($statusCode == 2) { 211 $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_REJECTED); 212 213 } else if ($statusCode == 3) { 214 $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_WAITING); 215 216 } else if ($statusCode == 4) { 217 $result->updateStatus(GTVerificationResultHttp::REVOCATION_WARNING); 218 219 } else if ($statusCode == 5) { 220 $result->updateStatus(GTVerificationResultHttp::REVOCATION_NOTIFICATION); 221 222 } 223 224 if ($statusCode == 0 || $statusCode == 1) { 225 226 try { 227 $timestamp->extend($response); 228 229 $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_EXTENDED); 230 231 } catch (GTException $e) { 232 233 $gtResult = new GTVerificationResult(); 234 $gtResult->updateErrors(GTVerificationResult::SYNTACTIC_CHECK_FAILURE); 235 236 $result->setGtResult($gtResult); 237 238 return $result; 239 } 240 241 $gtResult = $timestamp->verify($dataHash, $publicationsFile); 242 243 $result->setGtResult($gtResult); 244 245 } else if ($statusCode > 1) { 246 247 $failCode = ($response == null) ? -1 : $response->getFailCode(); 248 249 if ($failCode == -1) { 250 $result->updateErrors(GTVerificationResultHttp::SERVICE_UNREACHABLE_FAILURE); 251 252 } else if ($failCode == 0) { 253 $result->updateErrors(GTVerificationResultHttp::INVALID_ALGORITHM_FAILURE); 254 255 } else if ($failCode == 2) { 256 $result->updateErrors(GTVerificationResultHttp::INVALID_REQUEST_FAILURE); 257 258 } else if ($failCode == 5) { 259 $result->updateErrors(GTVerificationResultHttp::INVALID_DATA_FORMAT_FAILURE); 260 261 } else if ($failCode == 14) { 262 $result->updateErrors(GTVerificationResultHttp::TIME_NOT_AVAILBLE_FAILURE); 263 264 } else if ($failCode == 15) { 265 $result->updateErrors(GTVerificationResultHttp::UNACCEPTED_POLICY_FAILURE); 266 267 } else if ($failCode == 16) { 268 $result->updateErrors(GTVerificationResultHttp::UNACCEPTED_EXTENSION_FAILURE); 269 270 } else if ($failCode == 17) { 271 $result->updateErrors(GTVerificationResultHttp::ADDITIONAL_INFO_NOT_AVAILABLE_FAILURE); 272 273 } else if ($failCode == 25) { 274 $result->updateErrors(GTVerificationResultHttp::SYSTEM_FAILURE); 275 276 } else if ($failCode == 100) { 277 $result->updateErrors(GTVerificationResultHttp::TIMESTAMP_TOO_NEW_FAILURE); 278 279 } else if ($failCode == 101) { 280 $result->updateErrors(GTVerificationResultHttp::TIMESTAMP_TOO_OLD_FAILURE); 281 282 } 283 284 if ($failCode != 100 && $failCode != 101) { 285 return $result; 286 } 287 288 } 289 } 290 291 $gtResult = $timestamp->verify($dataHash, $publicationsFile); 292 293 $result->setGtResult($gtResult); 294 295 return $result; 296 } 297 298 299 /** 300 * Downloads publications file from the given url. 301 * 302 * Only basic syntax checking on the downloaded publications file is performaed. 303 * It is strongly recommended to verify the downloaded publications file. 304 * 305 * @static 306 * @throws GTException 307 * @param string $url publications file URL 308 * @return GTPublicationsFile publications file 309 */ 310 public static function getPublicationsFile($url) { 311 312 $curl = curl_init(); 313 314 curl_setopt($curl, CURLOPT_URL, $url); 315 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 316 curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); 317 318 $bytes = curl_exec($curl); 319 320 if ($bytes === false) { 321 throw new GTException("Error downloading publications file, CURL error: " . curl_error($curl)); 322 } 323 324 return new GTPublicationsFile(GTUtil::toByteArray($bytes)); 325 } 326 327} 328 329?> 330