Office 2010 Digital Signatures and XAdES

Shelley Gu, the program manager for Office signatures, has already posted the PM version of what we’ve done to improve digital signatures in the Office 2010 Engineering blog back in December. Her post is here. While Shelley did a nice job of an overview for the average user, I’d like to dive a bit more into detail. I also noticed that there are a bunch of comments to her post that haven’t been answered, and I’ll do that in a following post here.

While there have been a number of improvements, the biggest change has been the addition of XAdES. XAdES is an extension to the XML-DSig that provides for a number of improvements, and allows for very long-lived signatures. The first specification for XAdES showed up at, and dates back to 2003. The full, most recent specification is 1.4.1, and can be found at It takes a bit of poking around to find the exact link to the PDF, but I confirmed that the link worked and is valid as of this writing (5/30/2010).

Getting XAdES into Office turned out to be a bit of an adventure. It started off with a request to add time stamping support, and it all had to be done in a big hurry, and we’d decided not to use XAdES, because it was supposedly hard. The first iteration was very non-standard. Once I’d gotten it done, then all of a sudden we just had to use XAdES, and we were in a big hurry for that, too. Some grumbling ensued, but I went off and did it. We first implemented up to XAdES-T (explained in a moment), which is what shipped in beta 2. Some time passed, Shelley came along, and then we decided we just had to have nearly full XAdES support, taking us up to XAdES-X-L, and that needed to be done in a hurry, too (are you sensing a theme?). Getting that part done happened after beta 2, which was just short of a miracle – not much makes the bar at that stage of the game. We’ve ended up with XAdES support for Word, Excel, PowerPoint and InfoPath.

Now that I’ve been able to examine the gory details of XAdES, I’m really glad we chose to support it. The signatures we can create are far more robust than what went before, and best of all, they’re backwards compatible (at least to Office 2007 – Office 2003 is ignorant of XML signatures). There’s a bunch of cool (assuming you’re a signature geek) stuff to work with.

There are several levels to XAdES, and a bunch of optional elements that one could implement going forward – here’s the list:

  • BES – the most basic XAdES signature
  • EPES – same as above, but it has a SignaturePolicyIdentifier element. This is the form that we create by default, though it is only technically EPES – the SignaturePolicyIdentifier only has the default element.
  • T – adds a timestamp. I’d like it if this were the default, but we don’t have a default timestamp server.
  • C – adds hashes and verifying information for the certificate chain and the corresponding revocation responses, whether these are CRT or OCSP responses.
  • X – adds a timestamp that covers the original signature, and any information added in the T and C forms.
  • X-L – as above, but now we have full copies of the cert chain and the revocation responses.
  • A – archival – not yet implemented by Microsoft Office

OK, but what’s the reason for all this? The BES/EPES levels add a couple of minor items, and one that’s interesting and critical to have. The first is the SigningTime – this is something that’s not really in the XML-DSig standard, and we invented a reasonable way to store it in our app-specific Object. The existing implementation for ODF signatures in Open Office has done exactly the same thing. With XAdES support, now we have a standard way to store the signing time.

The second major item is the SigningCertificate element. This covers a really subtle attack that the XML-DSig specification didn’t think of. There are real world situations where a certificate server might re-issue a certificate that has the same public and private keys as a previously issued certificate. If you had 2 certificates with the same keys, then you could substitute one for the other, and XML-DSig wouldn’t be able to tell the difference – the signature would verify just fine. This doesn’t seem like a problem, but let’s say I had 2 certificates, one is expired, and the other isn’t. Now I sign a contract with the newer certificate, and later I want out of the contract. If I can substitute in the older certificate for the newer one, then I have an expired signature, and can repudiate the signature – it isn’t valid! The SigningCertificate element takes a hash of the full X509 data used to make the signature, and makes that part of the signed data – now these attacks can be caught.

There are a number of additional optional elements included in XAdES-BES/EPES that we don’t use yet – I’ll discuss those later.

The next level, XAdES-T is where you really get a lot of benefit. A serious problem with XML-DSig signatures is that they’re not good for the long term. You are typically given a certificate that’s good for 1-2 years, you sign something, and then open it 2 years later, and it’s invalid. We can’t replace pen and paper this way – real signatures have to be good for many years. The solution is a SignatureTimeStamp element. This uses RFC 3161 to record a timestamp of the signature value. Assuming that we can trust the timestamp server, we now have external proof of the signing time. This means that a future expiration doesn’t apply, and a revocation may not apply.

I’ll digress a bit and explain some of the ins and outs of expiration and revocation, and why an expired certificate should be treated the same as if it were revoked. A core problem with using CRLs (certificate revocation lists) is that they get big. When they get big, they can clog networks, and cause timeouts. One way to manage this is to just not keep revocation information for anything that’s expired – you’re not supposed to trust an expired cert in any case. Whether or not this happens is up to the CA operator, and hopefully will become less common as we all move to OCSP responses, which is a better system where you get an answer for that one cert, not all the certs that have ever been revoked.

If we can prove that something was signed prior to expiration, we can now safely ignore the expiration. Revocation is a different matter, and depends on when the revocation occurs and whether it was backdated. Let’s say I sign something today, and then next week find out that my certificate has been exposed to an attacker. I then figure out that the attacker got me a month ago, and I’d then go revoke the cert as of a month ago. The rub here is that if I verify the signature in the next few days, it seems valid. If I verify it in a month, then it was signed after the revocation happened, and it isn’t valid. If I verify it in 2 years, and the revocation information has gone away, now it’s valid again! So we’ve made some progress, but there’s clearly more to be done. Fortunately, XAdES has solutions for these problems as well.

An immediate solution is to not timestamp something immediately – you could add the timestamp later. As long as you add the timestamp prior to expiration, and check for validity at the time you add the timestamp, then we have more assurance of the revocation status. The second part of the solution is to go to the higher levels – and note that all of these are additive if you start with XAdES-BES/EPES.

XAdES-C is a little bit of an odd level. I can’t understand why anyone would ever use it in most real scenarios. What’s added here are hashes and issuer information for the entire certificate chain, and hashes and identifying information for the revocation responses. This assumes that we have some external store for the certificates and responses, but doesn’t say anything about where to go find them. We’ll allow you to create XAdES-C signatures, but I wouldn’t recommend it. If we have the extended levels, then this information becomes critical.

XAdES-X provides a key piece of critical assurance – now we add a timestamp over the signature, any XAdES-T timestamps, and the information we added for XAdES-C. This has now created a situation where we can identify that the certificate chain was valid, and revocation information was obtained at a specific point in time, and more importantly, protected the XAdES-C information from tampering. Like the predecessor, I don’t recommend stopping here.

XAdES-X-L now includes the full certificate chain, and full copies of the CRLs (these could get big) or OCSP responses (much better). If you’re going to go past XAdES-T, this is really the next practical stop.

If you can add all of this in stages – not a current capability of Office, but something that could be done with a utility – then if the XAdES-X-L information is added just prior to expiration, you now have a very high assurance that the signature is valid, nearly indefinitely. Ah, but cryptographic algorithms seem to degrade over time. In the time I’ve been working with these, we’ve seen MD5 go from shaky to useless, and SHA-1 will no longer meet EU or US standards as of 1/1/2011, which is right around the corner. SHA-1 isn’t in the same bucket as MD5, but we expect that it will get there. It isn’t out of the question that over time, the same thing will happen to SHA-256, and so on. To make matters worse, the public keys start getting creaky if they’re less than 2048 bits, and we can expect these to progressively degrade as well.

The solution to the problem of “algorithm rot” is in XAdES-A – this provides for an archival timestamp, and assuming that the archival timestamp uses a better set of algorithms, we’ve now extended the life of the signature. If you keep doing this on a regular basis, you could have a signature remain valid long after the original core crypto used to create it became worthless, which is a really neat trick. I’ve got a tremendous amount of respect for the people who created XAdES – they have a really elegant solution to a lot of problems. I’ve only found a few ambiguous parts of the specification that were a problem for me.

In addition to all the nice features above, there’s also a number of optional items that could be useful in the future:

  • SignaturePolicyIdentifier – what sort of signature is it? Full document, partial document?
  • CounterSignatures – these are obviously useful
  • DataObjectFormat – you sign what you see, and what you see should be what you sign. This can be used to help clarify just how to view the data.
  • ComittmentType – what you mean by this signature
  • SignatureProductionPlace – where you signed it
  • SignerRole – also obvious
  • Data objects timestamps – can be used to show when data were created

I’m also working with the ODF board to hopefully get XAdES signatures into the ODF 1.2 specification so that we can all create signatures that will interoperate between all of the implementers of the ODF standard. So far, my proposals seem to be well received, and really happy that it has gone well thus far.

Next post will cover some of the questions I see unanswered on Shelley’s post.

Comments (3)

  1. Nicob says:

    I'm more than surprised by your comment about backdated revocation. It's strictly forbidden for any PKI to backdate any revocation, especially for Qualified Certificates as described in the EU directive about electronic signature ! That's why, given a trusted time source, you can be sure at a given instant that the signature you receive is genuine (eventually via a dedicated Signature Validation Server).

    [dcl] That's a decision that the operator can make. It would make sense to do so, as there could be some time between breach of the key and discovery of breach of the key. If they want to make other decisions, that's up to them.

    [dcl] BTW, there's also a much shorter gap that could occur when not using OCSP. If the CRL is valid now, you won't refresh, but the revocation could have happened already. if some time passes between the actual signature and subsequently building the extended form of the signature, you have more confidence in the validity.

    [dcl] You made me curious, so I went poking around the RFC's – there's no mention of the possibility of a backdated revocation entry one way or the other. It makes more sense to disallow backdating if the private key is well protected – for example, something signed with a smart card or other trusted device has a higher assurance level than something signed where the private key is less well protected.

    I also don't think the Microsoft software makes it easy to do anything other than revoke something as of now. That said, any admin of a CA can get the CA to use its private key to sign CRLs, and could theoretically back date something – because there's nothing that completely prevents this from happening, I'll go back to my assertion that it is an operational decision. It is one of the things that makes dealing with certs very tricky – lots of corner cases.

  2. Nicob says:

    RFC 5280 ("Internet X.509 Public Key Infrastructure Certificate and CRL Profile") states in section 5.3.2 that you should instead use the "Invalidity Date" extension to indicate when a private key was compromised. It says too that the revocation date in the CRL entry is the date at which the CA processed the revocation (without backdating !!).

    I agree with you that backdated revocation is sometimes technically possible (depending on segregation of duties and complexity of the CA) but it should be explicitly described in the Certification Policy of the CA. And if a CA is backdating revocation, I'll NOT make any business with it !

    Invalidity Date :…/rfc5280

    [dcl] Thanks for the clarification. See the XAdES spec, section, in particular, note 4:

    Begin quote —-

    A grace period permits certificate revocation information to propagate through the revocation processes.

    This period could extend from the time an authorized entity requests certificate revocation, to when relying parties may be expected to have accessed the revocation information (for example, by contractual requirements placed on relying parties). In order to make sure that the certificate was not revoked at the time the signature was time-marked or time-stamped, verifiers SHOULD wait until the end of the grace period. An illustration of a grace period is provided figure 1.

    — End quote

    This shows that the designers of XAdES correctly allowed for the possibility of a certificate that seemed valid at signing time, and for various reasons, turned out to be invalid later. Yet another angle on the problem might be a cert chain that branches – one possible chain may have a longer CRL period than another. If the verification is done using different chains, based on the trust anchors of the verifier, then it is very possible to get different results at different times. If you perform the verification later on, towards the end of the grace period, you have a higher confidence that you're coming to the right conclusion.

    Further, I think you should read RFC 5280, section 5.3.2 more closely – it explicitly says (italics added for emphasis):

    The invalidity date is a non-critical CRL entry extension that
       provides the date on which it is known or suspected that the private
       key was compromised
    or that the certificate otherwise became invalid.
       This date may be earlier than the revocation date in the CRL entry,
       which is the date at which the CA processed the revocation
    .  When a
       revocation is first posted by a CRL issuer in a CRL, the invalidity
       date may precede the date of issue of earlier CRLs
    , but the
       revocation date SHOULD NOT precede the date of issue of earlier CRLs.
       Whenever this information is available, CRL issuers are strongly
       encouraged to share it with CRL users.

    Thus it is explicitly allowed and expected that an invalidity date may precede the date that the revocation entry was created, which only makes sense from an operational standpoint. If a thief breaks in and steals my private key while I am on vacation, and I only discover the theft 2 weeks later, I should not be liable for agreements the thief made prior to discovery.

  3. Nicob says:

    > A grace period permits certificate revocation information to propagate through the revocation processes.

    I agree. This can be implemented in the Signature Validation Server, which can answer OK / KO / HOLD.

    > If a thief breaks in and steals my private key while I am on vacation, and I only discover the theft 2 weeks later, I should not be liable for agreements the thief made prior to discovery.

    This depends of the contract which binds you and the CA. For example, credit cards in Europe only use the revocation date for liability limitation.

    > […] it is explicitly allowed and expected that an invalidity date may precede the date that the revocation entry was created.

    OK. However, this is not a "backdated revocation" as described in the article.

    [dcl] I agree that my terminology was imprecise, but this is exactly what I was trying to express. It has been a useful conversation – we now see there are at least 3 ways that you would get a OK revocation status at signing time that later turned out to be false:

    1. Local CRL is not out of date, but revocation happened previously
    2. Invalidity date preceeding revocation date
    3. Multiple chains resulting in differing revocation status due to lag in revocation notification

    The designers of XAdES wisely provided for these conditions by recommending that some time should ideally pass between adding the XAdES-T information and the additional levels, and that every time you add to the signature (-C, -X-L, -A), you have to validate it.