Skip to content

Commit 3ab497a

Browse files
committed
Update tcpdf.php
1 parent 80f70d3 commit 3ab497a

1 file changed

Lines changed: 33 additions & 111 deletions

File tree

tcpdf.php

Lines changed: 33 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,8 +1274,7 @@ class TCPDF {
12741274
* @protected
12751275
* @since 4.6.005 (2009-04-24)
12761276
*/
1277-
// protected $signature_max_length = 11742;
1278-
protected $signature_max_length = 20742;
1277+
protected $signature_max_length = 16742;
12791278

12801279
/**
12811280
* Data for digital signature appearance.
@@ -13646,7 +13645,7 @@ protected function getSignatureAppearanceArray($x=0, $y=0, $w=0, $h=0, $page=-1,
1364613645
* @since 6.0.090 (2014-06-16)
1364713646
*/
1364813647
// other options suggested to be implement: reqPolicy, nonce, certReq, extensions
13649-
// Also option to abort signing if timestamping failed and LTV enable (embed crl and or ocsp revocation info)
13648+
// and option to abort signing if timestamping failed and LTV enable (embed crl and or ocsp revocation info)
1365013649
public function setTimeStamp($tsa_host='', $tsa_username='', $tsa_password='', $tsa_cert='') {
1365113650
$this->tsa_data = array();
1365213651
if (!function_exists('curl_init')) {
@@ -13679,128 +13678,51 @@ protected function applyTSA($signature) {
1367913678
if (!$this->tsa_timestamp) {
1368013679
return $signature;
1368113680
}
13682-
//@TODO: implement this feature
13683-
// start timestamping
13684-
// by Hida (16 Mei 2023)
13685-
13686-
// Include minimum asn.1 fuctional script
13681+
// * @author Hida
1368713682
require_once(dirname(__FILE__).'/include/tcpdf_asn1.min.php');
13688-
1368913683
// Parse TCPDF's pkcs#7 Signature structure to get sequence of signed hash
1369013684
$pkcs7 = asn1parse($signature);
1369113685
$pkcs7ContentInfo = asn1parse($pkcs7[0][1]);
13692-
1369313686
$pkcs7content = asn1parse($pkcs7ContentInfo[1][1]);
13694-
1369513687
$pkcs7SignedData = asn1parse($pkcs7content[0][1]);
13696-
1369713688
$pkcs7signerInfos = asn1parse($pkcs7SignedData[4][1]);
13698-
1369913689
$SignerInfo = asn1parse($pkcs7signerInfos[0][1]);
13700-
1370113690
$pkcs7EncryptedDigest = $SignerInfo[5][1];
1370213691

1370313692
// Create timestamp request
13704-
13705-
// Create hash of encrypted contents TCPDF signature
13706-
// $this->setTimeStamp() have no options for change tsa req hash alg yet, so sha1 selected
1370713693
$hash = hash('sha1', hex2bin($pkcs7EncryptedDigest));
13708-
13709-
// Build timestamp request data
13710-
$tsReqData = seq(
13711-
int(1).
13712-
seq(
13713-
seq(
13714-
"06052B0E03021A". // Obj_sha1
13715-
"0500" // Null
13716-
).
13717-
oct($hash)
13718-
).
13719-
int(hash('crc32', rand())). // Add random nonce request
13720-
'0101ff' // set certReq true to tell TSA server to include SigningCertificate
13721-
);
13722-
13723-
$raw_data = hex2bin($tsReqData);
13724-
13725-
//Send request to TSA Server with Curl
13726-
if(extension_loaded('curl')) {
13727-
$ch = curl_init();
13728-
curl_setopt($ch, CURLOPT_URL, $this->tsa_data['tsa_host']);
13729-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
13730-
curl_setopt($ch, CURLOPT_POST, 1);
13731-
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
13732-
'Content-Type: application/timestamp-query',
13733-
'User-Agent: TCPDF'
13734-
)
13735-
);
13736-
curl_setopt($ch, CURLOPT_POSTFIELDS, $raw_data);
13737-
13738-
13739-
// can't send tsRequest, Timestamp failed!
13740-
if(!$tsResponse = curl_exec($ch)) {
13741-
return $signature;
13742-
}
13743-
13744-
// parse timestamp response data
13745-
$hexTsaResponse = bin2hex($tsResponse);
13746-
if(!$parseTimeStampResp = asn1parse($hexTsaResponse)) { // bad TSA Reponse
13747-
return $signature;
13748-
}
13749-
13750-
// verify tsa response PKIStatusInfo and TimeStampToken exists
13751-
if(!$TimeStampResp = asn1parse($parseTimeStampResp[0][1])) {
13752-
return $signature;
13753-
}
13754-
13755-
// Select timeStampToken only. must ignore response status data (in first sequence if exist, select 2nd sequence)
13756-
if(count($TimeStampResp) > 1) {
13757-
$TSTInfo = $TimeStampResp[1][1]; // TSTInfo
13758-
} else if (count($TimeStampResp) == 1) {
13759-
$TSTInfo = $TimeStampResp[0][1]; // TSTInfo
13760-
} else { // TimeStampResp not containts 1 or 2 fields
13761-
return $signature;
13762-
}
13763-
13764-
// Add timestamp in TCPDF Signature
13765-
// Create timestamp pkcs#7 data
13766-
$TimeStampToken = seq(
13767-
"060B2A864886F70D010910020E". // OBJ_id_smime_aa_timeStampToken
13768-
set(
13769-
seq(
13770-
$TSTInfo // TSTInfo
13771-
)
13772-
)
13773-
);
13774-
13775-
$time = seq(
13776-
$pkcs7signerInfos[0][1].
13777-
explicit(1,
13778-
$TimeStampToken
13779-
)
13780-
);
13781-
13782-
$pkcs7contentSignedData=seq(
13783-
int(1). // version
13784-
set($pkcs7SignedData[1][1]). // digestAlgorithms
13785-
seq($pkcs7SignedData[2][1]). // contentInfo
13786-
explicit(0,
13787-
$pkcs7SignedData[3][1]
13788-
). // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates
13789-
set(
13790-
$time
13791-
)
13792-
);
13793-
$pkcs7ContentInfo = seq(
13794-
"06092A864886F70D010702". // ContentType OBJ_pkcs7_signed
13795-
explicit(0,($pkcs7contentSignedData)) // content
13796-
).
13797-
// "0000"; // sometime needed for backward compatibility
13798-
"";
13799-
13800-
$signature = $pkcs7ContentInfo;
13694+
$tsReqData = seq(int(1).seq(seq("06052B0E03021A"."0500").oct($hash)).int(hash('crc32', rand())).'0101ff');
13695+
$binarytsReqData = hex2bin($tsReqData);
13696+
13697+
//Send request to TSA Server
13698+
$ch = curl_init();
13699+
curl_setopt($ch, CURLOPT_URL, $this->tsa_data['tsa_host']);
13700+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
13701+
curl_setopt($ch, CURLOPT_POST, 1);
13702+
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/timestamp-query','User-Agent: TCPDF'));
13703+
curl_setopt($ch, CURLOPT_POSTFIELDS, $binarytsReqData);
13704+
if(!$tsResponse = curl_exec($ch)) { return $signature; } // can't send tsRequest, Timestamp failed!
13705+
$hexTsaResponse = bin2hex($tsResponse); // parse timestamp response data
13706+
if(!$parseTimeStampResp = asn1parse($hexTsaResponse)) { return $signature; } // bad TSA Reponse
13707+
if(!$TimeStampResp = asn1parse($parseTimeStampResp[0][1])) { return $signature; } // verify tsa response PKIStatusInfo and TimeStampToken exists
13708+
13709+
// Select timeStampToken only. must ignore response status data (in first sequence if exist, select 2nd sequence)
13710+
if(count($TimeStampResp) > 1) {
13711+
$TSTInfo = $TimeStampResp[1][1]; // TSTInfo
13712+
} else if (count($TimeStampResp) == 1) {
13713+
$TSTInfo = $TimeStampResp[0][1]; // TSTInfo
13714+
} else { // TimeStampResp not containts 1 or 2 fields
13715+
return $signature;
1380113716
}
13717+
13718+
// Create timestamp pkcs#7 data
13719+
$TimeStampToken = seq("060B2A864886F70D010910020E".set(seq($TSTInfo)));
13720+
$time = seq($pkcs7signerInfos[0][1].explicit(1,$TimeStampToken));
13721+
$pkcs7contentSignedData=seq(int(1).set($pkcs7SignedData[1][1]).seq($pkcs7SignedData[2][1]).explicit(0,$pkcs7SignedData[3][1]).set($time));
13722+
$pkcs7ContentInfo = seq("06092A864886F70D010702".explicit(0,($pkcs7contentSignedData)));
13723+
13724+
$signature = $pkcs7ContentInfo;
1380213725
return $signature;
13803-
// End timestamping
1380413726
}
1380513727

1380613728
/**

0 commit comments

Comments
 (0)