#!/usr/bin/perl

use strict;
use warnings;
use Convert::ASN1;

# ASN.1 specification for TimeStampResponse (RFC 3161)
my $ASN1_SPEC = <<'__ASN1_RFC3161__';
TimeStampResponse ::= SEQUENCE {
    status                  PKIStatusInfo,
    timeStampToken          TimeStampToken OPTIONAL
}

PKIStatusInfo ::= SEQUENCE {
    status                  PKIStatus,
    statusString            PKIFreeText OPTIONAL,
    failInfo                PKIFailInfo OPTIONAL
}

PKIStatus ::= INTEGER

PKIFreeText ::= SEQUENCE OF UTF8String

PKIFailInfo ::= BIT STRING

TimeStampToken ::= ContentInfo

ContentInfo ::= SEQUENCE {
    contentType            OBJECT IDENTIFIER,
    content                [0] EXPLICIT ANY OPTIONAL
}
__ASN1_RFC3161__

my $asn1 = Convert::ASN1->new;
$asn1->prepare($ASN1_SPEC) or die "ASN.1 prepare error: " . $asn1->error;

my $tsr_codec = $asn1->find('TimeStampResponse')
    or die 'ASN.1 type TimeStampResponse not found';

my $contentinfo_codec = $asn1->find('ContentInfo')
    or die 'ASN.1 type ContentInfo not found';

# Read the TimeStampResponse file
my $tsr_file = 'test_data.tsr';
open my $fh, '<:raw', $tsr_file or die "Cannot open $tsr_file: $!";
local $/;
my $tsr_data = <$fh>;
close $fh;

print "TimeStampResponse file size: " . length($tsr_data) . " bytes\n";

# Decode the TimeStampResponse
my $tsr = $tsr_codec->decode($tsr_data);
if (!$tsr) {
    die "Failed to decode TimeStampResponse: " . $tsr_codec->error;
}

print "TimeStampResponse decoded successfully\n";
print "Status: " . ($tsr->{status}->{status} || 'unknown') . "\n";

# Extract the TimeStampToken (ContentInfo)
if ($tsr->{timeStampToken}) {
    my $token = $tsr->{timeStampToken};
    print "TimeStampToken found\n";
    print "ContentType: " . ($token->{contentType} || 'unknown') . "\n";
    
    # Encode the ContentInfo to DER
    my $token_der = $contentinfo_codec->encode($token);
    if ($token_der) {
        print "TimeStampToken DER size: " . length($token_der) . " bytes\n";
        
        # Write the ContentInfo to a file
        open my $out_fh, '>:raw', 'test_data_token.tsr' or die "Cannot create output file: $!";
        print $out_fh $token_der;
        close $out_fh;
        
        print "TimeStampToken saved to test_data_token.tsr\n";
    } else {
        die "Failed to encode TimeStampToken: " . $contentinfo_codec->error;
    }
} else {
    die "No TimeStampToken found in TimeStampResponse";
}
