setAlgorithm($dataHash->getHashAlgorithm()->getOid()); $message = new TSPMessageImprint(); $message->setHashedMessage($dataHash->getHashedMessage()); $message->setHashAlgorithm($algorithm); $request = new TSPTimeStampReq(); $request->setMessageImprint($message); $bytes = $request->encodeDER(); $bytes = GTUtil::fromByteArray($bytes); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $stamperUrl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $bytes); $bytes = curl_exec($curl); if ($bytes === false) { throw new GTException("Error creating timestamp, CURL error: " . curl_error($curl)); } $bytes = GTUtil::toByteArray($bytes); $response = new TSPTimeStampResp(); $response->decode(ASN1DER::decode($bytes)); return new GTTimestamp($response->getToken()); } /** * Extends the timestamp using the given extension service URL. * * @static * @throws GTException if timestamp extension fails * @param GTTimestamp $timestamp timestamp to be extended * @param string $verifierUrl extension service URL * @return void */ public static function extend(GTTimestamp $timestamp, $verifierUrl) { $request = new GTCertTokenRequest(); $request->setHistoryIdentifier(new GTBigInteger($timestamp->getProperty(GTTimestamp::HISTORY_ID))); $bytes = $request->encodeDER(); $bytes = GTUtil::fromByteArray($bytes); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $verifierUrl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $bytes); $bytes = curl_exec($curl); if ($bytes === false) { throw new GTException("Error extending timestamp, CURL error: " . curl_error($curl)); } $bytes = GTUtil::toByteArray($bytes); $response = new GTCertTokenResponse(); $response->decode(ASN1DER::decode($bytes)); $timestamp->extend($response); } /** * Verifies the given timestamp against the given dataHash. * * If a timestamp is not yet extended, automatic extension is attempted. * If the automatic extension is successfull the extended timestamp is verified * against the given publicationsFile. * * If the timestamp is already extended then the timestamp is verified against * the given publications file. * * If the timestamp is not extended and extension is not possible the timestamp * will be verified against short term signing certificates. * * @static * @throws GTException * @param GTTimestamp $timestamp the timestamp to verify * @param GTDataHash $dataHash data hash to verify the timestamp against * @param null|string $verifierUrl extension url if automatic extension is to be attempted, null otherwise * @param GTPublicationsFile $publicationsFile publications file to verify the timestamp against * * @return GTVerificationResultHttp tmestamp verification result */ public static function verify(GTTimestamp $timestamp, GTDataHash $dataHash, $verifierUrl, GTPublicationsFile $publicationsFile) { if (empty($timestamp)) { throw new GTException("Parameter timestamp is required"); } if (empty($dataHash)) { throw new GTException("Parameter dataHash is required"); } if ($publicationsFile == null) { throw new GTException("Invalid publications file: null"); } $result = new GTVerificationResultHttp(); if ($verifierUrl === null) { $extendable = false; } else { $extendable = $timestamp->isExtendable($publicationsFile); } if ($extendable) { $result->updateStatus(GTVerificationResultHttp::EXTENSION_ATTEMPTED); $request = new GTCertTokenRequest(); $request->setHistoryIdentifier(new GTBigInteger($timestamp->getProperty(GTTimestamp::HISTORY_ID))); $bytes = $request->encodeDER(); $bytes = GTUtil::fromByteArray($bytes); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $verifierUrl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $bytes); $bytes = curl_exec($curl); if ($bytes === false) { $result->updateStatus(GTVerificationResultHttp::SERVICE_UNREACHABLE_FAILURE); } $bytes = GTUtil::toByteArray($bytes); $response = null; try { $response = new GTCertTokenResponse(); $response->decode(ASN1DER::decode($bytes)); } catch (GTException $e) { $result->updateStatus(GTVerificationResultHttp::RESPONSE_FORMAT_FAILURE); return $result; } $statusCode = ($response === null) ? -1 : $response->getStatusCode(); if ($statusCode == 0) { $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_GRANTED); } else if ($statusCode == 1) { $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_GRANTED_WITH_MODS); } else if ($statusCode == 2) { $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_REJECTED); } else if ($statusCode == 3) { $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_WAITING); } else if ($statusCode == 4) { $result->updateStatus(GTVerificationResultHttp::REVOCATION_WARNING); } else if ($statusCode == 5) { $result->updateStatus(GTVerificationResultHttp::REVOCATION_NOTIFICATION); } if ($statusCode == 0 || $statusCode == 1) { try { $timestamp->extend($response); $result->updateStatus(GTVerificationResultHttp::TIMESTAMP_EXTENDED); } catch (GTException $e) { $gtResult = new GTVerificationResult(); $gtResult->updateErrors(GTVerificationResult::SYNTACTIC_CHECK_FAILURE); $result->setGtResult($gtResult); return $result; } $gtResult = $timestamp->verify($dataHash, $publicationsFile); $result->setGtResult($gtResult); } else if ($statusCode > 1) { $failCode = ($response == null) ? -1 : $response->getFailCode(); if ($failCode == -1) { $result->updateErrors(GTVerificationResultHttp::SERVICE_UNREACHABLE_FAILURE); } else if ($failCode == 0) { $result->updateErrors(GTVerificationResultHttp::INVALID_ALGORITHM_FAILURE); } else if ($failCode == 2) { $result->updateErrors(GTVerificationResultHttp::INVALID_REQUEST_FAILURE); } else if ($failCode == 5) { $result->updateErrors(GTVerificationResultHttp::INVALID_DATA_FORMAT_FAILURE); } else if ($failCode == 14) { $result->updateErrors(GTVerificationResultHttp::TIME_NOT_AVAILBLE_FAILURE); } else if ($failCode == 15) { $result->updateErrors(GTVerificationResultHttp::UNACCEPTED_POLICY_FAILURE); } else if ($failCode == 16) { $result->updateErrors(GTVerificationResultHttp::UNACCEPTED_EXTENSION_FAILURE); } else if ($failCode == 17) { $result->updateErrors(GTVerificationResultHttp::ADDITIONAL_INFO_NOT_AVAILABLE_FAILURE); } else if ($failCode == 25) { $result->updateErrors(GTVerificationResultHttp::SYSTEM_FAILURE); } else if ($failCode == 100) { $result->updateErrors(GTVerificationResultHttp::TIMESTAMP_TOO_NEW_FAILURE); } else if ($failCode == 101) { $result->updateErrors(GTVerificationResultHttp::TIMESTAMP_TOO_OLD_FAILURE); } if ($failCode != 100 && $failCode != 101) { return $result; } } } $gtResult = $timestamp->verify($dataHash, $publicationsFile); $result->setGtResult($gtResult); return $result; } /** * Downloads publications file from the given url. * * Only basic syntax checking on the downloaded publications file is performaed. * It is strongly recommended to verify the downloaded publications file. * * @static * @throws GTException * @param string $url publications file URL * @return GTPublicationsFile publications file */ public static function getPublicationsFile($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1); $bytes = curl_exec($curl); if ($bytes === false) { throw new GTException("Error downloading publications file, CURL error: " . curl_error($curl)); } return new GTPublicationsFile(GTUtil::toByteArray($bytes)); } } ?>