Sunday, February 4, 2018

How do I get the signature in a TimeStampToken (Bouncy Castle)

Leave a Comment

From RFC 3852 (and RFC 3161) I understand that the signature value is stored as an attribute of the SignerInfo type of the TimestampToken (which is a Signed Data content type).

How can I get that signature value from a TimeStampToken instance of Bouncy Castle (in C#)?

2 Answers

Answers 1

You could use class with helper methods:

public static class TimeStampTokenHelper {     public static IEnumerable<SignedData> GetTimeStampTokensAsSignedData(byte[] input)     {         var cmsInputStream = new Asn1InputStream(input);         var asn1Object = cmsInputStream.ReadObject();         Assert.IsNotNull(asn1Object);          var rootSequence = Asn1Sequence.GetInstance(asn1Object);         var signedData = GetSignedData(rootSequence);         return GetTimeStampTokensFromSignedData(signedData);     }      private static SignedData GetSignedData(Asn1Sequence sequence)     {         var rootContent = ContentInfo.GetInstance(sequence);         Assert.That(rootContent.ContentType.Id, Is.EqualTo("1.2.840.113549.1.7.2")); // signedData         var signedData = SignedData.GetInstance(rootContent.Content);         return signedData;     }      private static IEnumerable<SignedData> GetTimeStampTokensFromSignedData(SignedData signedData)     {         return GetTimeStampTokensFromSignerInfos(signedData.SignerInfos);     }      private static IEnumerable<SignedData> GetTimeStampTokensFromSignerInfos(Asn1Set signerInfos)     {         var timestampTokens = signerInfos             .OfType<Asn1Sequence>()             .SelectMany(GetTimeStampTokensFromSignerInfo);         return timestampTokens;     }      private static IEnumerable<SignedData> GetTimeStampTokensFromSignerInfo(Asn1Sequence signerInfoSequence)     {         var signerInfo = SignerInfo.GetInstance(signerInfoSequence);         var result = signerInfo.UnauthenticatedAttributes.ToArray()             .Select(Asn1Sequence.GetInstance)             .Where(x => ((DerObjectIdentifier)x.GetObjectAt(0)).Id == "1.2.840.113549.1.9.16.2.14")             .Select(x => GetSignedData(Asn1Sequence.GetInstance(Asn1Set.GetInstance(x.GetObjectAt(1)).GetObjectAt(0))));         return result;     } 

The TimeStampTokenHelper.GetTimeStampTokensAsSignedData helper method will extract time stamp token as SignedData structure. You may do everything you want with returned SignedData data.

Here is example how to extract signatures from SignerInfo:

var signatures = TimeStampTokenHelper.GetTimeStampTokensAsSignedData(cadesTBytes)     .SelectMany(token => token.SignerInfos.ToArray().Select(SignerInfo.GetInstance))     .Select(signerInfo => signerInfo.EncryptedDigest); 

As final tips:

  • you can use free online ASN.1 viewer to dig into structure of your Cades T signature
  • you can use Org.BouncyCastle.Asn1.Utilities.Asn1Dump.DumpAsString method to dump string representation of Bouncycastle's ASN.1 objects

Hope this helps.

Answers 2

I was able to get the signature using this:

CmsSignedData tsTokenCms = timestampToken.ToCmsSignedData(); SignerInformationStore signerInfoStore = tsTokenCms.GetSignerInfos(); SignerInformation signerInfo = signerInfoStore.GetFirstSigner(timestampToken.SignerID); byte[] signatureBytes = signerInfo.GetSignature(); string signatureString = BitConverter.ToString(signatureBytes); Console.WriteLine("Signature is: " + signatureString); 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment