New PB3 Feature - Digital Signatures

Digital signatures provide a way of verifying the source of a data item. The HealthRecordItem.TypeSpecificData XML is signed using the functionality present in the System.Security.Cryptography.Xml.SignedXml class.

The signing functionality shows up with 4 new items in the HealthRecordItem class:

  • IsSignatureValid();
  • Sign(X509Certificate2);
  • ValidateCertificate();
  • Collection<HealthRecordItemSignature> HealthRecordItemSignatures;

An item is signed using the following code:

    HealthRecordInfo record = base.CommonAuthenticatedConnection.GetPersonInfo().GetSelfRecord();
            
    X509Certificate2 cert = new X509Certificate2();
    cert.Import(".\\valid_cert.pfx");

    dataItem.Sign(cert);
    record.NewItem(thingItem);

A SignatureFailureException will be raised when a signature fails verification at the server.  Only certificates who have a CDP (CRL Distribution Point) Extended Property in the Certificate or who’s CA has the same property will validate because the platform verification includes checking against the certificate issuer’s CRL.

When fetching a data item, the signature information is not returned by default. To fetch it, you will need to specify the HealthRecordItemSections.Signature section:

    HealthRecordItem signedItem = 
            record.GetItem(itemId, HealthRecordItemSections.Core | HealthRecordItemSections.Xml | HealthRecordItemSections.Signature);

Now that we have fetched a signed item, we can call ValidateCertificate() to validate each of the certificates using X509Certificate2.Verify():

    signedItem.ValidateCertificate();

This method will throw an exception if validation fails. We can also call IsSignatureValid() to check whether the signature on the data item is valid. This is done by calling SignedXml.CheckSignature() for each signature on the data item.

Finally, you can access the signatures directly through the HealthRecordSignatures collection, and extract the certificate:

    foreach (HealthRecordSignatures signature in signedItem.HealthRecordSignatures)
    {
        X509Certificate2 certificate = signature.GetCertificate<X509Certificate2>();
    }